Saya memiliki skrip yang terhubung ke server jauh dan memeriksa apakah beberapa paket diinstal:
ssh root@server 'bash -s' < myscript.sh
myscript.sh:
OUT=`rpm -qa | grep ntpdate`
if [ "$OUT" != "" ] ; then
echo "ntpdate already installed"
else
yum install $1
fi
Contoh ini dapat disederhanakan. Inilah myscript2.sh
yang memiliki masalah yang sama:
read -p "Package is not installed. Do you want to install it (y/n)?" choise
Masalah saya adalah bahwa bash tidak dapat membaca jawaban saya secara interaktif.
Apakah ada cara untuk mengeksekusi skrip lokal dari jarak jauh tanpa kehilangan kemampuan untuk meminta pengguna?
Jawaban:
Coba sesuatu seperti ini:
The
-t
pasukan alokasi tty,$(<your_script)
membaca seluruh file dan dalam kasus ini melewati konten sebagai salah satu argumen untukssh
, yang akan dieksekusi oleh shell pengguna remote.Jika skrip membutuhkan parameter, berikan setelah skrip:
Bekerja untuk saya, tidak yakin apakah itu universal.
sumber
your script
, sambil tetap mempertahankan keunggulan sintaks yang Anda gunakan dalam jawaban Anda? Hanya menggunakanssh -t yourserver "$(<your_script --some_arg)"
hasil dalambash: --some_arg: command not found
.ssh ... $(<script) script_arg1 script_arg2 ...
Masalah Anda adalah
ssh
memulai shell yang non-interaktif di mesin remote. Solusi mudah yang jelas adalah menyalin skrip ke server jauh dan menjalankannya dari sana:Jika penyalinan bukanlah suatu pilihan untuk alasan apa pun, saya akan memodifikasi skrip untuk menghubungkan terlebih dahulu dan memeriksa apakah
$1
sudah diinstal, kemudian menyambung kembali dan menginstal seperlunya:sumber
$OUT=$(ssh root@server rpm -qa | grep "$1");
keluar dan kemudian koneksi ke-2 akan mengambil waktu sebanyak yang pertama. Apakah aku salah?ssh -M foo.example.com sleep 99999999
ataussh -M foo.example.com read <somefifo
sebagai master dan bunuh secara eksplisit (dengankill
atauecho done >somefifo
) ketika Anda selesai.Ini penjelasan yang bagus .
Jadi saya mengadaptasi skrip untuk
dan ini tidak berhasil.
jadi saya memindahkan script ke remote untuk menghindari redirection lokal di ssh. (Perintah saya ada di file bernama f )
Ini berhasil. Inilah hasilnya:
Seperti @terdon menyebutkan bahwa kehebatan aslinya adalah untuk menjalankan skrip lokal dari jarak jauh, salinan jarak jauh dapat diotomatisasi, ini hanya satu contoh semua pada satu baris.
sumber
bash -s < script.sh
seperti OP lakukan? Bisakah Anda memasukkan penjelasan dalam jawaban Anda alih-alih menghubungkannya?Saya telah mencari solusi untuk masalah ini beberapa kali di masa lalu, namun tidak pernah menemukan yang sepenuhnya memuaskan. Menyalurkan ke ssh kehilangan interaktivitas Anda. Dua koneksi (scp / ssh) lebih lambat, dan file sementara Anda mungkin dibiarkan tergeletak. Dan seluruh skrip pada baris perintah sering berakhir di neraka.
Baru-baru ini saya menemukan bahwa ukuran buffer baris perintah biasanya cukup besar ('getconf ARG_MAX> 2MB di mana saya melihat). Dan ini membuat saya berpikir tentang bagaimana saya bisa menggunakan ini dan mengurangi masalah pelarian.
Hasilnya adalah:
atau menggunakan dokumen dan kucing di sini:
Saya telah memperluas gagasan ini untuk menghasilkan skrip contoh BASH yang berfungsi penuh
sshx
yang dapat menjalankan skrip arbitrer (tidak hanya BASH), di mana argumen dapat berupa file input lokal juga, di atas ssh. Lihat di sini .sumber
"
karakter yang harus diloloskan. Dan juga dibatasi untuk skrip BASH. Solusi saya adalah kasus umum untuk konten skrip apa pun dari bahasa scripting yang diinstal. Selanjutnya, di sshx saya lebih lanjut menunjukkan file argumen serialisasi, yang cukup bagus.echo "$(cat my_script | base64)" | base64 --decode
Penampilan Anda setara (-ish) untukcat my_script | base64 | base64 --decode
, yang terlihat sangat mirip no-op.echo "ARG1=$1, USER=$USER, END"
. a)$ ssh host "$(<my_bash)" foo
->ARG1=, USER=user, END foo
. b)$ ssh host bash "<(echo $(cat my_bash|base64) | base64 --decode)" foo
->ARG1=foo, USER=user, END
. Di sini (a) berjalan secara efektif:bash -c $'#!/bin/bash\necho "ARG1=$1, USER=$USER, END" foo'
atau sesuatu yang serupa. Perhatikan arg tidak bekerja. Mana (b) adalah berjalan:bash <(echo IyEvY...5EIgo= | base64 --decode) foo
. (2) Saya menggunakan base64 sebagai encoding transport.