Я хочу иметь возможность отправлять сигналы (SIGINT является наиболее важным) через SSH.
Эта команда:
ssh server "sleep 1000;echo f" > foo
начнет спать на сервере и через 1000 секунд поместит 'f \ n' в файл foo на моей локальной машине. Если я нажму CTRL-C (то есть отправлю SIGINT в ssh), это убьет ssh, но не остановит sleep на удаленном сервере. Я хочу, чтобы это убило сон на удаленном сервере.
Итак, я попробовал:
ssh server -t "sleep 1000;echo f" > foo
Но если stdin не терминал, я получаю эту ошибку:
Pseudo-terminal will not be allocated because stdin is not a terminal.
и тогда SIGINT все еще не передан.
Итак, я попробовал:
ssh server -t -t "sleep 1000;echo f" > output
Но тогда вывод в foo - это не 'f \ n', а вместо 'f \ r \ n', что губительно в моей ситуации (так как мой вывод - двоичные данные).
Выше я использую «sleep 1000; echo f», но на самом деле он предоставляется пользователем, поэтому он может содержать все, что угодно. Однако, если мы можем заставить его работать для «сна 1000; эхо f», мы, скорее всего, можем заставить его работать для всех реалистичных ситуаций.
Я действительно не беспокоюсь о получении псевдо-терминала на другом конце, но я не смог найти какой-либо другой способ заставить ssh переслать мой SIGINT.
Есть ли другой способ?
Редактировать:
Пользователь может давать команды, которые читают двоичные данные из стандартного ввода, такие как:
seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo
Пользователь может давать команды, которые интенсивно используют процессор, такие как:
ssh server "timeout 1000 burnP6"
Edit2:
Версия, которая, кажется, работает для меня:
your_preprocessing |
uuencode a | ssh -tt -oLogLevel=quiet server "stty isig -echoctl -echo ; uudecode -o - |
your_command |
uuencode a" | uudecode -o - |
your_postprocessing
Спасибо digital_infinity за указание в правильном направлении.
ssh
должно быть более сложным, чем то, что вы показываете в качестве примеров, потому что вы можете получить желаемое поведение с помощью простой перестановки:sleep 1000 && ssh server "echo f" > foo
(Должно быть&&
, нет;
, так что убийствоsleep
препятствует выполнениюssh
команды.) Если я Правильно, пожалуйста, сделайте ваши примеры более репрезентативными для вашего фактического использования, чтобы можно было дать лучший ответ.Ответы:
Краткий ответ:
и остановите программу, нажав CTRL + N.
Длинное объяснение:
stty
опцию,intr
чтобы изменить свой сервер или локальный символ прерывания, чтобы не конфликтовать друг с другом. В приведенной выше команде я изменил символ прерывания сервера на CTRL + N. Вы можете изменить свой локальный символ прерывания и оставить его на сервере без каких-либо изменений.stty -echoctl
.stty isig
SIGINT
сигналtrap '/bin/true' SIGINT
с пустым заявлением. Без ловушки у вас не будет никакого стандартного сигнала после сигнала SIGINT на вашем конце.источник
seq 1000 | gzip | ssh -tt dell-test "zcat|bzip2" | bzcat > foo
тоже не работает. Чтобы эта команда работала, нам нужно удалить-tt
. Таким образом, для выделения псевдотерминала, вероятно, потребуется некоторая информация от 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
. Хотя символ прерывания не работает - нам нужен какой-то метод передачи для символа прерывания, когда стандартный ввод занят .Я перепробовал все решения, и это было лучшим:
/programming/3235180/starting-a-process-over-ssh-using-bash-and-then-killing-it-on-sigint/25882610#25882610
источник
sleep
процесс в случае потери соединения.sleep
, не так ли? Я добавил некоторыеdate >> /tmp/killed
послеcat
, но это не сработало. Есть ли тайм-аут? Я использую Zsh нормально, но также протестировал его с bash в качестве оболочки удаленного входа.-o ServerAliveInterval=3 -o ServerAliveCountMax=2
позволяет быстро его обнаружить, но есть ли что-то для серверной стороны?Я думаю, что вы можете найти PID процесса, который вы запускаете на сервере, и отправить сигнал, используя другую
ssh
команду (например, так:)ssh server "kill -2 PID"
.Я использую этот метод для отправки сигналов реконфигурации приложениям, работающим на другом компьютере (мои приложения перехватывают SIGUSR1 и читают файл конфигурации). В моем случае найти PID легко, потому что у меня есть уникальные имена процессов, и я могу найти PID, отправив
ps
запрос черезssh
.источник
Решение превратилось в http://www.gnu.org/software/parallel/parallel_design.html#Remote-Ctrl-C-and-standard-error-stderr
источник
----- command.sh
----- на местном терминале
источник