Удаленная команда PuTTY, содержащая цикл while

Я пытаюсь автоматизировать несколько общих задач, которые я SSH в удаленный сервер, чтобы сделать. Для этого я использую PuTTY и его опцию "удаленная команда" (соединение > SSH) в нескольких сохраненных сеансах. Моя удаленная команда выглядит примерно так:

~/scripts/test; $SHELL -l

сценарий, выполняемый отличается за сохраненный сеанс и выполняет различные задачи. $SHELL -l сохраняет сеанс PuTTY активным после завершения выполнения скрипта.

все это отлично работает для большинства скриптов я бегущий. Однако у меня есть тот, который использует цикл while для выполнения серии команд до тех пор, пока он не завершится Ctrl+C. сценарий запускается нормально, но оболочка PuTTY не остается активной после его завершения. $SHELL -l не выполняется.

пример скрипта с таким поведением выглядит следующим образом:

while true; do
echo "."
sleep 2
done

следующие работы отлично выполняются вручную, я вижу ожидаемый результат от второй команды:

~/scripts/test; echo "done"

впрочем, второе команда шпатлевки "удаленная команда" не выполняется. Действительно, если я изменю удаленную команду на echo, он не отображается.

~/scripts/test; echo "done"; $SHELL -l

Итак, я думаю, мой вопрос: почему вторая команда в списке не выполняется удаленной командой, в то время как она выполняется вручную? И, что более важно, что я могу поделать?

если это актуально, я запускаю PuTTY на Ubuntu 14.04.

5
задан oogles
источник

2 ответов

при выполнении putty или ssh--Я не думаю, что есть какая-то разница в этом контексте--с командой для запуска на удаленной системе удаленный сервер ssh запускает команду как команду оболочки:

/bin/bash -c '~/scripts/test; $SHELL -l'

так у вас bash экземпляр в удаленной системе, выполняющей этот конвейер. У вас также есть другой bash экземпляр, запущенный первым экземпляром, выполняющим этот" тестовый " скрипт.

при вводе Control-C,putty посылает символ на пульт система, в которой ваш TTY интерпретирует его как символ прерывания. Это приводит к в посылке SIGINT (сигнала прерывания) к процессам которые прикреплены к TTY. Это прерывает оба этих процесса оболочки, заставляя их выйти. Вы хотите, чтобы родительский экземпляр оболочки игнорировал SIGINT.

команду bash, чтобы игнорировать сигнал SIGINT-это:

trap "" INT

Итак, чтобы отключить SIGINT для вашего конвейера, вы изменили бы исходную команду на:

trap '' INT; ~/scripts/test; $SHELL -l

но это также отключает SIGINT для дочерних процессов, что делает сценарий" test " невосприимчивым к Ctrl-C. Поэтому вам нужно повторно включить SIGINT для тестового сценария. Команда для этого:

trap INT

вы можете добавить эту строку в сам тестовый скрипт или в конвейер:

trap '' INT; ( trap INT; ~/scripts/test ); $SHELL -l

теперь, когда вы нажмете Ctrl-C, вы должны прервать процесс "test", но не родительский процесс, который выполняет конвейер команд.

вы можете проверить это без использования putty или ssh. Просто запустите эти команды и попробуйте нажать Ctrl-C во время выполнения "сна":

bash -c 'sleep 15; echo foo'                  # Ctrl-C kills sleep; doesn't print "foo"
bash -c 'trap "" INT ; sleep 15; echo foo'    # Ctrl-C has no effect
bash -c 'trap "" INT; ( trap INT; sleep 15 ); echo foo'    # Kills sleep, prints "foo"
2
отвечен Kenster 2014-07-24 01:54:06
источник

ctrl+c для удаленной команды putty фактически прерывает сеанс ssh, поэтому следует ожидать, что он не выполняет оставшиеся удаленные команды. Если ваша цель состоит в том, чтобы сеанс продолжал оставаться активным, вашего бесконечного цикла должно быть достаточно.

0
отвечен Faiz R 2014-07-24 00:27:32
источник

Другие вопросы bash linux putty ssh