Saya ingin dapat mengirim sinyal (SIGINT adalah yang paling penting) melalui ssh.
Perintah ini:
ssh server "sleep 1000;echo f" > foo
akan mulai tidur di server dan setelah 1000 detik akan meletakkan 'f \ n' di file foo di mesin lokal saya. Jika saya menekan CTRL-C (yaitu mengirim SIGINT ke ssh) itu akan mematikan ssh, tetapi tidak akan mematikan sleep di server jauh. Saya ingin mematikan tidur di server jauh.
Jadi saya mencoba:
ssh server -t "sleep 1000;echo f" > foo
Tetapi jika stdin bukan terminal saya mendapatkan kesalahan ini:
Pseudo-terminal will not be allocated because stdin is not a terminal.
dan kemudian SIGINT masih belum diteruskan.
Jadi saya mencoba:
ssh server -t -t "sleep 1000;echo f" > output
Tapi kemudian output di foo bukan 'f \ n' tetapi sebaliknya 'f \ r \ n' yang merupakan bencana dalam situasi saya (karena output saya adalah data biner).
Di atas saya menggunakan "sleep 1000; echo f", tetapi pada kenyataannya yang disediakan oleh pengguna, sehingga dapat berisi apa saja. Namun, jika kita dapat membuatnya berfungsi untuk "sleep 1000; echo f" kita kemungkinan besar dapat membuatnya bekerja untuk semua situasi yang realistis.
Saya benar-benar tidak peduli tentang mendapatkan terminal semu di ujung lain, tetapi saya tidak dapat menemukan cara lain untuk mendapatkan ssh untuk meneruskan SIGINT saya.
Apakah ada cara lain?
Edit:
Pengguna dapat memberikan perintah yang membaca data biner dari stdin, seperti:
seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo
Pengguna dapat memberikan perintah yang intensif cpu, seperti:
ssh server "timeout 1000 burnP6"
Sunting2:
Versi yang sepertinya berfungsi untuk saya adalah:
your_preprocessing |
uuencode a | ssh -tt -oLogLevel=quiet server "stty isig -echoctl -echo ; uudecode -o - |
your_command |
uuencode a" | uudecode -o - |
your_postprocessing
Terima kasih kepada digital_infinity karena mengarahkan saya ke arah yang benar.
ssh
harus lebih rumit daripada apa yang Anda tunjukkan sebagai contoh, karena Anda bisa mendapatkan perilaku yang Anda inginkan dengan penataan ulang sederhana:sleep 1000 && ssh server "echo f" > foo
(Itu harus&&
, tidak;
, sehingga pembunuhansleep
mencegahssh
perintah untuk menjalankan.) Jika saya Benar, tolong jadikan contoh Anda lebih representatif dari penggunaan Anda yang sebenarnya, sehingga jawaban yang lebih baik dapat diberikan.Jawaban:
Jawaban singkat:
dan hentikan program dengan CTRL + N.
Penjelasan panjang:
stty
opsiintr
untuk mengubah server atau karakter interupsi lokal agar tidak saling bertabrakan. Pada perintah di atas saya telah mengubah karakter interupsi server menjadi CTRL + N. Anda dapat mengubah karakter interupsi lokal dan membiarkan karakter server tanpa perubahan.stty -echoctl
.stty isig
SIGINT
sinyaltrap '/bin/true' SIGINT
dengan pernyataan kosong. Tanpa jebakan, Anda tidak akan memiliki stdout setelah sinyal SIGINT di ujung Anda.sumber
seq 1000 | gzip | ssh -tt dell-test "zcat|bzip2" | bzcat > foo
tidak berhasil juga. Agar perintah ini berfungsi, kita perlu menghapus-tt
. Jadi alokasi terminal semu mungkin mengambil beberapa input dari stdin(sleep 1; seq 1000 ) | gzip | uuencode bin | ssh -tt dell-test "stty isig intr ^N -echoctl -echo ; trap '/bin/true' SIGINT; sleep 1; uudecode -o /dev/stdout | zcat |bzip2 | uuencode bin2 " | uudecode -o /dev/stdout | bzcat >foo
. Walaupun karakter interrupt tidak berfungsi - kita memerlukan beberapa metode transmisi untuk karakter interrupt ketika stdin sibuk .Saya mencoba semua solusi dan ini yang terbaik:
/programming/3235180/starting-a-process-over-ssh-using-bash-and-then-killing-it-on-sigint/25882610#25882610
sumber
sleep
proses jika koneksi terputus.sleep
, bukan? Saya telah menambahkan beberapadate >> /tmp/killed
setelahcat
, tetapi tidak dipicu. Apakah ada batas waktu? Saya menggunakan Zsh secara normal, tetapi juga mengujinya dengan bash sebagai shell login jarak jauh.-o ServerAliveInterval=3 -o ServerAliveCountMax=2
memungkinkan untuk mendeteksi dengan cepat, tetapi apakah ada sesuatu untuk sisi server?Saya pikir Anda bisa menemukan PID dari proses yang Anda jalankan di server dan mengirim sinyal menggunakan
ssh
perintah lain (seperti inissh server "kill -2 PID"
:).Saya menggunakan metode ini untuk mengirim sinyal konfigurasi ulang ke aplikasi yang berjalan pada mesin yang berbeda (aplikasi saya menangkap SIGUSR1 dan membaca file konfigurasi). Dalam kasus saya, menemukan PID itu mudah, karena saya memiliki nama proses yang unik dan saya dapat menemukan PID dengan mengirimkan
ps
permintaan melaluissh
.sumber
Solusinya berkembang menjadi http://www.gnu.org/software/parallel/parallel_design.html#Remote-Ctrl-C-and-standard-error-stderr
sumber
----- command.sh
----- di terminal lokal
sumber