Cara mencetak "$" di sini-dokumen

42

Bagaimana saya bisa menggaungkan "$" di sini-doc di bash?

Sebagai contoh, saya ingin memiliki file dengan konten di server jarak jauh suka $ABC=home_dir.

$ ssh hostname sudo -s <<EOF
echo "$ABC=home_dir" > file
EOF

Tetapi itu akan diperlakukan sebagai variabel. Bagaimana saya bisa mencetak literal $?

pengguna21485
sumber
2
Anda dapat menggunakan tanda kutip tunggal
Rahul Patil
2
Itu banyak tipuan yang terjadi. Anda yakin tidak dapat membuat file di host lokal dan kemudian scp?
l0b0

Jawaban:

65

Jika Anda ingin menulis dokumen di sini dan Anda tidak ingin dokumen APAPUN diperluas atau karakter khusus apa pun ditafsirkan, Anda dapat mengutip label dengan tanda kutip tunggal, seperti ini:

$ cat >file <<'EOF'
echo "$ABC=home_dir"
EOF

Namun, situasi Anda seperti yang dijelaskan dalam contoh Anda jauh lebih kompleks, karena Anda benar-benar mengirim konten ini melalui ssh, ke sistem jarak jauh, untuk dijalankan oleh sudo yang juga menggunakan shell (dan agar shell akan memperluas kontennya) demikian juga). Anda akan memerlukan lebih banyak tingkat kutipan untuk mendapatkan ini dengan benar, tetapi bahkan dengan itu masih tidak akan berhasil karena sudo memerlukan terminal (sehingga dapat meminta kata sandi) dan Anda telah diarahkan dari stdin. Bahkan menggunakan ssh -ttidak akan membantu di sini.

Saya juga setuju dengan Johan. Tidak jelas apakah ini yang Anda inginkan; perhatikan bahwa tidak sah untuk memberikan nilai ke referensi variabel shell, jadi jika file yang Anda coba buat ini seharusnya berupa skrip shell, itu tidak akan berfungsi seperti yang Anda jelaskan. Mungkin jika Anda sedikit mencadangkan dan menjelaskan apa yang benar - benar ingin Anda lakukan, kami dapat membantu lebih banyak.

Ilmuwan gila
sumber
Ini adalah jawaban terbaik karena dapat memenuhi dokumen SINI yang sangat lama. Itu (kebanyakan) adalah bukti idiot.
Felipe Alvarez
22

Melarikan diri $

$ ssh hostname sudo -s <<EOF
echo "\$ABC=home_dir" > file
EOF

Aku tidak tahu apa kasus penggunaan Anda tetapi biasanya Anda ingin home_dir=$ABCbukan $ABC=home_dir.

lesmana
sumber
2
Solusi ini akan berhasil, tetapi apakah itu benar-benar yang diinginkan OP? Tampaknya menghasilkan skrip shell yang ketika dieksekusi akan menyimpan dalam "file" string yang akan merujuk ABC untuk sisi kiri dari tugas dan kemungkinan berakhir menyimpan =home_dirke file? Tentu saja saya tidak tahu apa gunanya ...
Johan
2
Hal ini akan menyebabkan literal suatu $yang akan dikirim ke remote shell, tapi kemudian itu shell akan memperluas $ABCsebelum menggemakan string untuk file. Untuk menulis literal $ke file, Anda akan memerlukan backslash (melarikan diri) lain:, echo "\\\$ABC=home_dir"sehingga shell remote menerima echo "\$ABC=home_dir".
chepner
9

Cara pelarian yang termurah adalah

$ ssh hostname sudo -s << \EOF
echo "$ABC=home_dir" > file
EOF
Bernhard
sumber
4

Anda menghemat sedikit kutipan dengan mengirimkan string ke catproses di ujung jarak jauh:

echo 'echo $ABC=home_dir' | ssh hostname sudo -s "cat > file"

Kutipan tunggal melindungi $di ujung lokal, dan string tidak pernah dilihat oleh shell di sisi lain karena dibaca langsung oleh cat(via sudo), daripada menjadi argumen ke perintah shell lain.

Dengan kode Anda, Anda perlu lapisan tambahan untuk melindungi $:

$ ssh hostname sudo -s <<EOF
echo "\\\$ABC=home_dir" > file
EOF

Anda perlu mengirim literal \$ke host jarak jauh, sehingga shell jarak jauh akan menulis literal $ke file. Anda juga dapat menyederhanakan ini dengan mengutip penanda di sini-doc:

$ ssh hostname sudo -s <<\EOF
echo "\$ABC=home_dir" > file
EOF
chepner
sumber