Per jawaban zanco , Anda tidak menyediakan perintah jarak jauh ssh, mengingat bagaimana shell mem-parsing baris perintah. Untuk mengatasi masalah ini, ubah sintaks sshpermintaan 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 bashdan sh, dan mungkin juga shell lain, solusi paling sederhana adalah dengan hanya menggabungkan sshpermintaan 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/bashakan menghasilkan peringatan Pseudo-terminal will not be allocated because stdin is not a terminal. Perhatikan juga yang EOTdikelilingi oleh tanda kutip tunggal, sehingga bashmengenali 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/bashberlaku untuk di atas.
Pendekatan lain yang valid adalah untuk meneruskan perintah jarak jauh multi-line sebagai string tunggal, menggunakan beberapa lapisan bashinterpolasi 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@serverdiuraikan oleh bash, dan ditafsirkan sebagai sshperintah, diikuti oleh argumen user@serveruntuk diteruskan ke sshperintah
"memulai string interpolasi, yang ketika selesai, akan terdiri dari argumen untuk diteruskan ke sshperintah, yang dalam hal ini akan ditafsirkan dengan sshmenjadi perintah jarak jauh untuk dieksekusi sebagaiuser@server
$( memulai perintah yang akan dieksekusi, dengan output yang ditangkap oleh string interpolasi sekitarnya
catadalah perintah untuk menampilkan isi file apa pun yang mengikuti. Output dari catakan 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
EOTmengakhiri nowdoc, menghasilkan file sementara nowdoc dibuat dan diteruskan kembali ke catperintah panggilan . catoutput 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 sshsebagai argumen baris perintah tunggal, yang sshakan 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 readbuilt-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…