Saya memiliki skrip bash yang memulai skrip python3 (sebut saja startup.sh
), dengan baris kunci:
nohup python3 -u <script> &
Ketika saya ssh
masuk dan langsung memanggil skrip ini, skrip python terus berjalan di latar belakang setelah saya keluar. Namun, ketika saya menjalankan ini:
ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> "./startup.sh"
Proses berakhir segera setelah ssh
selesai menjalankannya dan menutup sesi.
Apa perbedaan keduanya?
EDIT: Skrip python menjalankan layanan web melalui Bottle.
EDIT2: Saya juga mencoba membuat skrip init yang memanggil startup.sh
dan menjalankan ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> "sudo service start <servicename>"
, tetapi mendapatkan perilaku yang sama.
EDIT3: Mungkin ada sesuatu yang lain dalam naskah. Inilah sebagian besar skrip:
chmod 700 ${key_loc}
echo "INFO: Syncing files."
rsync -azP -e "ssh -i ${key_loc} -o StrictHostKeyChecking=no" ${source_client_loc} ${remote_user}@${remote_hostname}:${destination_client_loc}
echo "INFO: Running startup script."
ssh -i ${key_loc} -o StrictHostKeyChecking=no ${remote_user}@${remote_hostname} "cd ${destination_client_loc}; chmod u+x ${ctl_script}; ./${ctl_script} restart"
EDIT4: Ketika saya menjalankan baris terakhir dengan tidur di akhir:
ssh -i ${key_loc} -o StrictHostKeyChecking=no ${remote_user}@${remote_hostname} "cd ${destination_client_loc}; chmod u+x ${ctl_script}; ./${ctl_script} restart; sleep 1"
echo "Finished"
Tidak pernah sampai echo "Finished"
, dan saya melihat pesan Server botol, yang belum pernah saya lihat sebelumnya:
Bottle vx.x.x server starting up (using WSGIRefServer())...
Listening on <URL>
Hit Ctrl-C to quit.
Saya melihat "Selesai" jika saya secara manual SSH masuk dan mematikan proses sendiri.
EDIT5: Menggunakan EDIT4, jika saya membuat permintaan ke titik akhir, saya mendapatkan halaman kembali, tetapi Botol keluar:
Bottle vx.x.x server starting up (using WSGIRefServer())...
Listening on <URL>
Hit Ctrl-C to quit.
----------------------------------------
Exception happened during processing of request from ('<IP>', 55104)
sumber
strace
jika Anda menggunakan Linux atautruss
jika Anda menjalankan Solaris dan melihat bagaimana / mengapa itu berakhir. Seperti misalnyassh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> strace -fo /tmp/debug ./startup.sh
.&
di akhir skrip start up? Menambahkan&
menghilangkan ketergantungan sesi ssh Anda dari menjadi id induk (ketika id orangtua mati begitu juga anak-anak mereka). Juga saya pikir ini adalah pertanyaan rangkap berdasarkan posting sebelumnya ini . Posting yang saya kirimkan kepada Anda dalam kalimat sebelumnya adalah duplikat dari posting ini yang mungkin memberikan detail yang lebih baik.nohup ./startup.sh &
sebelumnya, tetapi memiliki perilaku yang sama.startup.sh
sudah mengandung fork (nohup python3 -u <script> &
), jadi saya cukup yakin saya tidak perlu fork lagi.Jawaban:
Saya akan memutuskan perintah dari input standar / output dan aliran kesalahan:
ssh
membutuhkan indikator yang tidak memiliki output lagi dan tidak memerlukan input lagi. Memiliki sesuatu yang lain menjadi input dan mengarahkan output berartissh
dapat keluar dengan aman, karena input / output tidak datang atau pergi ke terminal. Ini berarti input harus berasal dari tempat lain, dan output (baik STDOUT dan STDERR) harus pergi ke tempat lain.Bagian ini
</dev/null
menentukan/dev/null
sebagai input untuk<script>
. Mengapa itu berguna di sini:Sebagai alternatif, pengalihan dari sumber input lain harus relatif aman selama
ssh
sesi saat ini tidak perlu tetap terbuka.Dengan
>/dev/null
bagian shell mengarahkan output standar ke / dev / null pada dasarnya membuangnya.>/path/to/file
juga akan bekerja.Bagian terakhir
2>&1
adalah mengarahkan kembali STDERR ke STDOUT.sumber
nohup python3 -u <script> >/dev/null 2>&1 &
dannohup python3 -u <script> > nohup.out 2>&1 &
bekerja. Saya pikir nohup secara otomatis mengalihkan semua output - apa bedanya?nohup
yang Anda miliki di host jarak jauh? POSIXnohup
tidak diperlukan untuk mengalihkanstdin
, yang saya lewatkan, tetapi harus tetap mengarahkanstdout
danstderr
.nohup (GNU coreutils) 8.21
.nohup
mencetak pesan, sukanohup: ignoring input and appending output to ‘nohup.out’
?Lihatlah
man ssh
:Saat Anda menjalankan,
ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> "./startup.sh"
Anda menjalankan skrip shell startup.sh sebagai perintah ssh.Dari uraian:
Berdasarkan ini, itu harus menjalankan skrip dari jarak jauh.
Perbedaan antara itu dan berlari
nohup python3 -u <script> &
di terminal lokal Anda adalah bahwa ini berjalan sebagai proses latar belakang lokal sementara perintah ssh mencoba untuk menjalankannya sebagai proses latar belakang jarak jauh.Jika Anda bermaksud menjalankan skrip secara lokal maka jangan jalankan startup.sh sebagai bagian dari perintah ssh. Anda mungkin mencoba sesuatu seperti
ssh -i <keyfile> -o StrictHostKeyChecking=no <user>@<hostname> && "./startup.sh"
Jika niat Anda adalah menjalankan skrip dari jarak jauh dan Anda ingin proses ini berlanjut setelah sesi ssh Anda dihentikan, Anda harus terlebih dahulu memulai
screen
sesi pada host jarak jauh. Maka Anda harus menjalankan skrip python di dalam layar dan itu akan terus berjalan setelah Anda mengakhiri sesi ssh Anda.Lihat Panduan Pengguna Layar
Meskipun saya pikir layar adalah pilihan terbaik Anda, jika Anda harus menggunakan nohup, pertimbangkan untuk mengatur
shopt -s huponexit
pada host jarak jauh sebelum menjalankan perintah nohup. Atau, Anda dapat menggunakandisown -h [jobID]
untuk menandai proses sehingga SIGHUP tidak akan dikirim ke sana. 1Juga, lihat ringkasan ini tentang cara
huponexit
kerjanya ketika shell keluar, terbunuh atau jatuh Saya menduga masalah Anda saat ini terkait dengan bagaimana sesi shell berakhir. 2Akhirnya, berikut adalah beberapa contoh cara menggunakan shopt huponexit. 3
sumber
bash
halaman manual,huponexit
seharusnya hanya memengaruhi shell interaktif dan bukan skrip - 'Jika opsi shell huponexit telah disetel dengan shopt, bash mengirimkan SIGHUP ke semua pekerjaan ketika shell login interaktif keluar.'Mungkin patut dicoba
-n
saat memulaissh
? Ini akan mencegah ketergantungan proses jarak jauh pada lokalstdin
, yang tentu saja menutup segera setelahssh session
berakhir. Dan ini akan menyebabkan penghentian harga jarak jauh setiap kali ia mencoba mengaksesnyastdin
.sumber
Saya menduga Anda memiliki kondisi balapan. Ini akan seperti ini:
Jika ssh tidak memotong masalah, berikut ini akan terjadi (tidak yakin tentang urutan keduanya):
Jadi dua langkah kritis terakhir tidak terjadi, karena startup.sh dan ssh selesai sebelum nohup punya waktu untuk melakukan hal itu.
Saya berharap masalah Anda akan hilang jika Anda meletakkan beberapa detik tidur di akhir startup.sh. Saya tidak yakin persis berapa banyak waktu yang Anda butuhkan. Jika penting untuk mempertahankannya seminimal mungkin, maka mungkin Anda dapat melihat sesuatu di proc untuk melihat kapan itu aman.
sumber
/proc/$!/comm
apakahnohup
portable atau tidak menggunakan outputps -o comm= $!
.Ini terdengar lebih seperti masalah dengan apa yang dilakukan
python
skrippython
itu sendiri. Semua yangnohup
benar - benar dilakukan (bilah penyederhanaan pengalihan) hanya mengatur handler untukHUP
sinyalSIG_IGN
(abaikan) sebelum menjalankan program. Tidak ada yang menghentikan program pengaturannya kembaliSIG_DFL
atau menginstal handler sendiri setelah mulai berjalan.Satu hal yang mungkin ingin Anda coba adalah melampirkan perintah Anda dalam tanda kurung sehingga Anda mendapatkan efek garpu ganda dan
python
skrip Anda bukan lagi anak dari proses shell. Misalnya:Hal lain yang mungkin juga patut dicoba (jika Anda menggunakan
bash
dan bukan shell lain) adalah menggunakandisown
builtin bukannohup
. Jika semuanya berfungsi seperti yang didokumentasikan ini seharusnya tidak benar-benar membuat perbedaan, tetapi dalam shell interaktif ini akan menghentikanHUP
sinyal menyebar kepython
skrip Anda . Anda dapat menambahkan penolakan pada baris berikutnya atau yang sama seperti di bawah ini (perhatikan menambahkan;
setelah a&
adalah kesalahan dalambash
):Jika kombinasi di atas atau sebagian tidak berfungsi maka pasti satu-satunya tempat untuk mengatasi masalah ini adalah dalam
python
skrip itu sendiri.sumber
huponexit
hal - hal tersebut, menjalankan subshell harus memiliki efek yang samadisown
seperti proses tidak akan ditambahkan ke daftar pekerjaan.disown
. Tapi jangan berharap itu akan membuat banyak perbedaan. Saya pikir Anda bertaruh terbaik adalah dengan mengubahpython
skrip sehingga memberitahu Anda mengapa itu keluar.nohup
melakukannya.Saya pikir itu karena pekerjaan terkait dengan sesi. Setelah itu semua pekerjaan pengguna berakhir juga.
sumber
Jika
nohup
dapat membuka file outputnya, Anda mungkin memiliki petunjuknohup.out
. Mungkinpython
tidak di jalan ketika Anda menjalankan skrip viassh
.Saya akan mencoba membuat file log untuk perintah. Coba gunakan:
sumber
ssh
untuk menjalankan skrip secara manual, jadi saya mengasumsikan python3 ada di jalur.