Menggunakan SSH untuk memulai proses dari jarak jauh

18

Saya telah menulis skrip yang saya gunakan untuk mendorong dan menggunakan layanan baru ke beberapa mesin di bawah kendali saya, dan untuk menjalankan proses saya menggunakan ssh untuk memulai proses dari jarak jauh. Sayangnya, setiap kali saya menggunakan SSH untuk memulai proses, perintah SSH sepertinya tidak pernah kembali, menyebabkan script terhenti.

Perintah ini ditentukan sebagai: ssh $ user @ $ host "/ root / command &". Setiap kali saya menjalankan perintah sederhana, seperti ps atau siapa, perintah SSH segera kembali, namun ketika saya mencoba dan memulai proses saya, itu tidak kembali. Saya telah mencoba trik seperti membungkus proses saya dalam skrip bash sederhana yang memulai proses dan kemudian keluar, namun ini juga menggantung perintah SSH (bahkan jika skrip bash menggemakan pesan sukses, dan keluar secara normal).

Adakah yang tahu apa yang menyebabkan perilaku ini, dan bagaimana saya bisa mendapatkan perintah SSH untuk kembali segera setelah proses dimulai?

Terima kasih atas wawasan Anda!

rmrobins
sumber
Posting baris perintah persis yang Anda gunakan ... menghilangkan kata sandi / nama pengguna / IP
Joseph Kern
ssh $ SSH_USER @ $ HOST_ADDR "/ root / AppName &"
rmrobins
Saya harus menyebutkan bahwa saya telah mengatur kunci SSH, jadi tidak perlu menggunakan kata sandi untuk menjalankan perintah pada sistem jarak jauh.
rmrobins
@rmrobins, langkah yang sangat bagus - mengatur auth kunci publik.
nik

Jawaban:

28

SSH menghubungkan stdin, stdout dan stderr dari remote shell ke terminal lokal Anda, sehingga Anda dapat berinteraksi dengan perintah yang berjalan di sisi jarak jauh.

Sebagai efek samping, itu akan terus berjalan sampai koneksi ini ditutup, yang terjadi hanya ketika perintah jarak jauh dan semua anak-anaknya (!) Telah berakhir (karena anak-anak, yang merupakan awal dari "&", mewarisi std * dari mereka proses induk dan tetap buka).

Jadi, Anda perlu menggunakan sesuatu seperti

ssh user@host "/script/to/run < /dev/null > /tmp/mylogfile 2>&1 &"

<,> Dan 2> & 1 mengarahkan ulang stdin / stdout / stderr dari terminal Anda. Tanda "&" kemudian membuat skrip Anda masuk ke latar belakang. Dalam produksi Anda tentu saja akan mengarahkan ulang stdin / err ke logfile yang sesuai.

Lihat

http://osdir.com/ml/network.openssh.general/2006-05/msg00017.html

Edit:

Hanya menemukan bahwa < /dev/nulldi atas tidak diperlukan (tapi mengarahkan stdout / err is ). Tidak tahu kenapa ...

sleske
sumber
Terima kasih, ini adalah persis apa yang saya cari - tidak terpikir oleh saya bahwa proses akan mewarisi std * bahkan ketika menggunakan & untuk meluncurkannya di latar belakang.
rmrobins
+1! Bekerja untukku. Dan Anda juga dapat mencetak hasilnya dengan menggema file log: ssh user@host "/script/to/run > /tmp/ssh.stdout 2>&1 && cat /tmp/ssh.stdout && rm -f /tmp/ssh.stdout"
Fishdrowned
5

Anda bisa mencoba nohup . Man nohup untuk detail lebih lanjut.

ssh host "nohup script &"

Jika Anda ingin menyimpan output pada mesin jarak jauh, inilah varian .

ssh user@host 'export REMOTE=myname; nice nohup ./my-restart >
logfile.log 2>&1 &'
Jauder Ho
sumber
5

Alternatif lain adalah menyalakan yang terpisah screen(1), seperti:

ssh -l user host "screen -d -m mycommand"

Ini akan memulai layar terpisah (yang menangkap semua interaksi di dalamnya) dan kemudian segera kembali, mengakhiri sesi ssh.

Dengan sedikit kecerdikan, Anda dapat memecahkan panggilan perintah jarak jauh yang cukup rumit dengan cara ini.

towo
sumber
4
 -f      Requests ssh to go to background just before command execution.
         This is useful if ssh is going to ask for passwords or
         passphrases, but the user wants it in the background.  This
         implies -n.  The recommended way to start X11 programs at a
         remote site is with something like ssh -f host xterm.

         If the ExitOnForwardFailure configuration option is set to “yes”,
         then a client started with -f will wait for all remote port for‐
         wards to be successfully established before placing itself in the
         background.
Teddy
sumber
1
Masalah dengan metode ini adalah bahwa perintah SSH tidak benar-benar dihentikan, itu hanya tersembunyi di latar belakang, sehingga host yang menjalankan skrip akan memiliki sejumlah besar perintah SSH di latar belakang yang tidak pernah kembali karena perintah SSH tidak pernah kembali ( yaitu akar masalah saya berharap untuk memecahkan)
rmrobins
-1

Saya pikir cara yang benar adalah

ssh user@host exec script.sh &
nik
sumber
Tidak, itu tidak berhasil untuk saya. Kenapa harus begitu?
sleske
Saya belum pernah menggunakan latar belakang push ssh, sedang mencoba tanpa istilah di tangan. salahku.
nik