Per jawaban zanco , Anda tidak menyediakan perintah jarak jauh ssh
, mengingat bagaimana shell mem-parsing baris perintah. Untuk mengatasi masalah ini, ubah sintaks ssh
permintaan perintah Anda sehingga perintah jarak jauh terdiri dari string multi-line yang benar secara sintaksis.
Ada berbagai sintaks yang bisa digunakan. Misalnya, karena perintah dapat disalurkan ke bash
dan sh
, dan mungkin juga shell lain, solusi paling sederhana adalah dengan hanya menggabungkan ssh
permintaan shell dengan heredocs:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Perhatikan bahwa mengeksekusi tanpa di atas /bin/bash
akan menghasilkan peringatan Pseudo-terminal will not be allocated because stdin is not a terminal
. Perhatikan juga yang EOT
dikelilingi oleh tanda kutip tunggal, sehingga bash
mengenali heredoc sebagai nowdoc , mematikan interpolasi variabel lokal sehingga teks perintah akan diteruskan apa adanya ssh
.
Jika Anda seorang penggemar pipa, Anda dapat menulis ulang di atas sebagai berikut:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Peringatan yang sama tentang /bin/bash
berlaku untuk di atas.
Pendekatan lain yang valid adalah untuk meneruskan perintah jarak jauh multi-line sebagai string tunggal, menggunakan beberapa lapisan bash
interpolasi variabel sebagai berikut:
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
Solusi di atas memperbaiki masalah ini dengan cara berikut:
ssh user@server
diuraikan oleh bash, dan ditafsirkan sebagai ssh
perintah, diikuti oleh argumen user@server
untuk diteruskan ke ssh
perintah
"
memulai string interpolasi, yang ketika selesai, akan terdiri dari argumen untuk diteruskan ke ssh
perintah, yang dalam hal ini akan ditafsirkan dengan ssh
menjadi perintah jarak jauh untuk dieksekusi sebagaiuser@server
$(
memulai perintah yang akan dieksekusi, dengan output yang ditangkap oleh string interpolasi sekitarnya
cat
adalah perintah untuk menampilkan isi file apa pun yang mengikuti. Output dari cat
akan diteruskan kembali ke dalam string penangkap interpolasi
<<
memulai bash heredoc
'EOT'
menetapkan bahwa nama heredoc adalah EOT. Kutipan tunggal '
seputar EOT menentukan bahwa heredoc harus diuraikan sebagai nowdoc , yang merupakan bentuk khusus dari heredoc di mana isinya tidak diinterpolasi oleh bash, tetapi diteruskan dalam format literal
Konten apa pun yang ditemui di antara <<'EOT'
dan <newline>EOT<newline>
akan ditambahkan ke output nowdoc
EOT
mengakhiri nowdoc, menghasilkan file sementara nowdoc dibuat dan diteruskan kembali ke cat
perintah panggilan . cat
output nowdoc dan meneruskan output kembali ke string interpolasi menangkap
)
menyimpulkan perintah yang akan dieksekusi
"
menyimpulkan string yang diinterpolasi menangkap. Isi dari string yang diinterpolasi akan dikembalikan ssh
sebagai argumen baris perintah tunggal, yang ssh
akan ditafsirkan sebagai perintah jarak jauh untuk dieksekusi sebagaiuser@server
Jika Anda perlu menghindari menggunakan alat eksternal seperti cat
, dan tidak keberatan memiliki dua pernyataan, bukan satu, gunakan read
built-in dengan heredoc untuk menghasilkan perintah SSH:
IFS='' read -r -d '' SSH_COMMAND <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
ssh user@server "${SSH_COMMAND}"
ssh user@server /bin/bash <<EOT…