meneruskan dan mengatur variabel dalam heredoc

18

Saya memiliki skrip yang harus melakukan banyak hal berbeda pada banyak mesin jarak jauh yang berbeda. Saya berpikir bahwa heredoc akan bekerja untuk ini, tetapi saya tidak dapat menggunakan variabel yang didefinisikan di tempat lain dalam skrip dan satu didefinisikan dalam heredoc.

Ini beberapa kode:

#!/bin/sh

FOO="foo"
ssh some.remote.host << EOF
  BAR="bar"
  echo "FOO=$FOO"
  echo "BAR=$BAR"
EOF

Ini hanya mencetak yang berikut ini:

FOO =

BAR = bar

Namun, jika saya mengutip garis EOF seperti ini: ssh some.remote.host << "EOF" maka ia hanya mencetak yang berikut ini:

FOO = foo

BAR =

Adakah petunjuk tentang bagaimana saya dapat menggunakan kedua variabel di dalam heredoc?

Terima kasih.

trubliphone
sumber

Jawaban:

27

Singkatnya, gunakan:

  • kata kunci heredoc yang tidak dikutip, misalnya, EOF
  • char dolar reguler untuk variabel luar (yaitu lokal ), misalnya,$FOO
  • melarikan diri karakter dolar untuk variabel dalam (yaitu jarak jauh ), mis\$BAR

Jika Anda membiarkan kata kunci heredoc (yaitu EOF) tidak dikutip, maka tubuh heredoc diproses secara lokal, sehingga $FOOdiperluas ke foodan BARdiperluas ke string kosong. Maka sshperintah Anda menjadi:

BAR="bar"
echo "FOO=foo"
echo "BAR="

Jika Anda mengutip kata kunci heredoc maka ekspansi variabel ditekan, sehingga sshperintah Anda menjadi ini:

BAR="bar"
echo "FOO=$FOO"
echo "BAR=$BAR"

Karena FOOmungkin tidak didefinisikan di lingkungan shell jauh, ekspresi "FOO=$FOO"dievaluasi sebagai "FOO=''", yaitu FOOdiatur ke string kosong.

Jika Anda ingin menggunakan kedua variabel maka Anda harus membiarkan kata kunci heredoc tidak dikutip, sehingga ekspansi variabel terjadi untuk variabel yang ditentukan secara lokal, dan kemudian melarikan diri (dengan garis miring terbalik) variabel yang ingin Anda kembangkan dari jarak jauh, yaitu :

#!/bin/sh

FOO="foo"
ssh some.remote.host << EOF
  BAR="bar"
  echo "FOO=$FOO"
  echo "BAR=\$BAR"
EOF

Dalam hal ini perintah ssh Anda (seperti yang diterima oleh server jauh) akan menjadi sebagai berikut:

  BAR="bar"
  echo "FOO=foo"
  echo "BAR=$BAR"
igal
sumber
1
Itu mengagumkan! Saya telah menghabiskan waktu lama untuk mencari tahu hal ini. Terima kasih banyak atas solusi ini.
trubliphone