Bunuh proses melahirkan oleh ssh ketika ssh mati

23

Ini adalah pertanyaan yang telah dibahas beberapa kali, tidak hanya di sini, tetapi juga di situs lain dari jaringan pertukaran stack (mis. Bagaimana membuat ssh untuk mematikan proses jarak jauh ketika saya menyela ssh sendiri? ). Namun, saya tidak dapat membuat solusi apa pun berhasil untuk saya.

Saya menjalankan perintah melalui ssh. Setiap kali saya keluar ssh, saya ingin perintah untuk mati juga. Perintah ini adalah daemon bernama ktserver yang berjalan tanpa batas hingga Anda menekan Ctrl-C.

Saya menjalankannya sebagai berikut: ssh -t compute-0-1 ktserverdan, memang, ketika saya menekan Ctrl-C, proses berakhir dengan anggun dan sesi ssh berakhir.

Namun, jika alih-alih menekan Ctrl-C, saya membunuh proses ssh menggunakan killperintah (misalnya, mengirim SIGINT atau SIGHUP), ktserverprosesnya tetap hidup.

Bagaimana saya bisa membuat orang ktservermati selalu independen tentang bagaimana sshdibunuh?

EDIT : Jika, bukannya ktserversaya menjalankan sesuatu yang sama sekali berbeda, seperti gedit, semuanya berfungsi seperti pesona (yaitu gedit mati ketika koneksi mati). Karena itu, mungkin ada sesuatu yang salah dengan proses itu sendiri. Sebagai contoh, saya berpikir bahwa itu mungkin mengabaikan SIGHUP atau SIGINT. Namun, ketika saya menjalankan kill -1 ktserveratau kill -2 ktserver, proses mati seperti yang diharapkan.

EDIT2 : Seperti yang ditunjukkan oleh Mark Plotnick, masalah ini terkait dengan fakta bahwa tidak ada komunikasi yang beredar di saluran ssh. Saya telah mengkonfirmasi dengan menjalankan ssh -t <host> readdan mematikan proses ssh sesudahnya. readmasih hidup dan menendang.

GermanK
sumber
Sudahkah Anda mencoba kill -9 ktserver?
@HermanTorjussen Tentu, itu berhasil. Masalahnya adalah bahwa perintah ini dijalankan dari dalam proses lain dan saya mungkin tidak memiliki kendali atas semua banyak kemungkinan yang mungkin menyebabkan proses saya mati, dan oleh karena itu sesi ssh dengannya. Jadi saya perlu cara yang dapat diandalkan untuk memastikan bahwa setiap kali proses saya - dan karena itu ssh- mati, ktserver akan mati bersama mereka.
GermanK
Pengalaman saya dengan Linux adalah bahwa jika perintah jarak jauh tidak melakukan i / o ke koneksi tcp mati, itu akan tetap berjalan. ssh example.com dd ...Pekerjaan saya sudah selesai sampai berjam-jam bahkan setelah sshkoneksi mati karena masalah jaringan. Jika Anda dapat mengubah ktserveruntuk mengambil opsi untuk mengeluarkan sesuatu sesekali, itu mungkin merupakan solusi.
Mark Plotnick
@MarkPlotnick Memang, saya sudah mencoba menjalankan readdi komputer jauh, dan setelah membunuh koneksi ssh, readtidak mati. Sayangnya, saya tidak dapat mengubah ktserver untuk menghasilkan apa pun. Tidak ada solusi kalau begitu?
GermanK
2
Saya berasumsi bahwa ketika ssh mati shell Anda juga mati. Anda dapat mengonfigurasi shell Anda untuk mengirim sinyal -1 (SIGHUP) ketika itu berakhir. ( shopt -s huponexit). Bisakah Anda menguji apakah ini cocok untuk Anda?
Hennes

Jawaban:

13

Biasanya ketika koneksi ssh mati, shell juga mati. Anda dapat mengonfigurasi shell Anda untuk mengirim sinyal -1 (SIGHUP) ketika berakhir untuk semua anak-anaknya.

Untuk bash Anda dapat mengonfigurasi opsi ini melalui perintah shopin builtin . ( shopt -s huponexit).

Untuk zsh yang Anda inginkan .setoptHUP

Hennes
sumber
Saya pikir ini adalah jawaban untuk masalah saya saat ini, tetapi sepertinya tidak berhasil. Saya menjalankan: ssh $ host "scp LargeFile.dat $ OtherHost: / tmp" & pid = $! dan kemudian mencoba menghentikan transfer itu dengan: shopt -s huponexit; bunuh $ pid, tetapi scp tidak berhenti ketika saya membunuh ssh yang saya mulai. Adakah pikiran?
David Doria
Bisakah Anda menguji dengan opsi shell yang ditetapkan sebelum memulai perintah scp? Atau dengan memulai shell, pengaturan shopt dan mulai scp?
Hennes
2
Ini bekerja untuk saya, tetapi saya harus terlebih dahulu memastikan saya menggunakan ssh -t -t, (perhatikan -tdua kali!) Yang memaksa alokasi tty, bukan hanya pty.
Nicolas Wu
13

Saya menemukan bahwa hanya menggunakan -t -tsebagai argumen untuk sshmembuatnya berfungsi. Saya tidak harus mengatur huponexitke shell yang berasal atau jauh.

Saya menguji ini sebagai berikut:

Tidak bekerja:

ssh user@remote sleep 100
^C

Ini membunuh sesi ssh, tapi saya bisa melihat proses tidur masih berjalan pada remote host ( ps -ef | grep sleepmenunjukkannya).

Apakah berhasil:

ssh -t -t user@remote sleep 100
^C

Ini membunuh sesi ssh dan proses tidur jarak jauh juga terbunuh. Saya juga telah memverifikasi bahwa sinyal yang dikirim ke proses jarak jauh adalah SIGINTjika Anda menggunakan Control- C. Saya juga memverifikasi bahwa SIGKILL (-9) yang diterapkan pada sshproses juga akan mematikan proses jarak jauh.

EDIT 1:

Itu adalah benar untuk sleep... untuk proses jauh lebih keras kepala, saya menemukan bahwa sshpegangan ^ C berbeda yang SIGINT. Ctrl- Cbekerja, tetapi kill -INT $pidtidak

Inilah yang akhirnya saya dapatkan yang berfungsi untuk aplikasi saya yang sebenarnya (mencuri dari jawaban lain).

ssh -t -t -i id_rsa user@mic0 "/bin/sh -O huponexit -c 'sleep 100'"

Perhatikan penggunaan tanda kutip ganda dan tunggal. Perhatikan bahwa proses jarak jauh Anda HARUS menanggapi SIGHUP dengan benar-benar keluar!

Mark Lakata
sumber
Ini bekerja paling baik untuk saya, tetapi FYI, itu juga menyebabkan karakter terminal kontrol berdarah, yang dapat menyebabkan output lucu. Jadi, solusi mudah dalam kasus saya adalah membungkus perintah yang disebut dan menyalurkan output mereka cat. Misalnya,ssh -ttq user@host '{ cmd; cmd; } | cat'
Droj
Ctrl-C TIDAK selalu sama dengan kill -INT $pid , lihat jawaban saya di unix.stackexchange.com/questions/377191/… dan yang lain di stackoverflow.com/questions/8398845/... untuk detail lebih jelas ;-)
thecarpy
@ thecarpy - jawaban pertama Anda mengatakan Ctrl-C mirip dengan SIGINT , dan jawaban lainnya mengatakan ^Cmengirim SIGINT . Jadi apa perbedaan yang tepat jika mereka tidak setara?
Mark Lakata
1

Jika ssh tidak menyebarkan sinyal, ia menerima apa yang Anda harapkan darinya?

UPD. (khusus untuk JosephR): itu jelas merupakan kesalahan dalam pertanyaan itu sendiri yang mengikuti dari kesalahpahaman - "Bunuh proses yang ditimbulkan oleh ssh ketika ssh mati". SSH biasanya tidak menelurkan proses (terkadang memang demikian, tetapi ini adalah cerita lain), sebaliknya SSHD melakukannya, ketika kita melihat sisi lain dari koneksi. SSH hanya mengandalkan server remote abstraksi abseaksi terminal. Itu sebabnya satu-satunya hal yang dapat membantu ada kemampuan terminal untuk memancarkan sinyal ke proses terlampir. Ini agak sangat mendasar untuk setiap sistem mirip UNIX.

poige
sumber
1
Ini tidak memberikan jawaban untuk pertanyaan itu. Untuk mengkritik atau meminta klarifikasi dari penulis, tinggalkan komentar di bawah posting mereka.
Anthon
@Anthon, ini penjelasan. Tapi tidak ada yang menyatakan ini harus menjadi satu-satunya jawaban yang benar. Terima kasih atas komentar Anda di bawah ini.
poige
1
@poige Mungkin menyempurnakan penjelasannya sehingga bisa digunakan untuk OP dan lainnya.
Joseph R.
@ JosephRR., Ok, hanya untukmu.
poige
1
Jika saya mengatakan "Bunuh proses yang dihasilkan oleh sshd ketika koneksi ssh terputus" apakah itu terdengar lebih baik bagi Anda? Saya tidak berpikir bahwa mengulang kata memecahkan masalah saya dengan cara apa pun.
GermanK
0

Solusi yang diposting di sini tidak bekerja untuk saya tetapi karena pertanyaan ini muncul pertama kali ketika saya sedang mencari solusi untuk masalah yang sama dan juga -t -ttrik yang disebutkan di sini saya akan memposting solusi yang bekerja untuk saya untuk orang lain untuk mencoba.

ssh -t -t -o ControlMaster=auto -o ControlPath='~/test.ssh' your_remote_ip_goes_here "your_long_running_command" &
sleep 100
ssh -o ControlPath='~/test.ssh' -O exit your_remote_ip_goes_here

Perintah jangka panjang saya tidak berjalan lagi ketika koneksi terputus seperti ini.

Greg0ry
sumber