3

У меня есть команда в сценарии npm, которая соединяет SSH с удаленным сервером сборки и запускает сценарий Bash. Сценарий устанавливает файл блокировки и вызов trap для удаления файла блокировки при выходе из сценария.

Я отменяю операцию ctrl+C в обоих случаях.

LOCKFILEPATH="/tmp/env_app.lock"
# cleanup function just deletes $LOCKFILEPATH
function mutex() {
  if [ -f "$LOCKFILEPATH" ]; then
    echo -e "\n\n${redtext}Build already in progress! Exiting.${resettext}\n\n";
    exit 1;
  else
    touch $LOCKFILEPATH;
    trap cleanup EXIT;
  fi
}

Это прекрасно работает, когда вы впервые запускаете SSH на хосте, но ловушка не работает, когда вы отправляете команду через SSH с

ssh hostname command

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

 trap cleanup EXIT SIGHUP SIGKILL SIGTERM SIGINT

Что мне здесь делать?

Я также настроил более простой сценарий, и он, кажется, работал нормально при выполнении его вручную по SSH. Может быть, есть дополнительные слои, когда я запускаю его, используя скрипт npm? Сценарий npm:

"deploy": "ssh HOSTNAME ''deploy-script $(git rev-parse --abbrev-ref HEAD) stage $npm_package_config_deploy_target yes''",

который просто проверяет текущее имя ветки и использует его для развертывания на хосте сборки. Такой же как

"deploy": "ssh HOSTNAME ''deploy-script CURRENTBRANCH stage APPNAME''",

ОБНОВЛЕНИЕ: добавление силы tty -t к сценарию npm, кажется, исправило это. Это сбивает с толку, так как мне не нужно это для простого сценария. Может быть, я порождаю слишком много подпроцессов в большом скрипте (слишком много, чтобы вставить его здесь, не редактируя кучу), поэтому для запуска ловушки очистки требуется tty.

"deploy": "ssh -t HOSTNAME ''deploy-script CURRENTBRANCH stage APPNAME''",

1 ответ1

2

Когда вы делаете

ssh hostname command

а затем Ctrl+C, вы завершаете локальный ssh . command по- прежнему работает на удаленной стороне, он никогда не получает ваше нажатие клавиши. Это отличается от -t . Смотрите этот ответ для объяснения. Соответствующий фрагмент:

На стороне клиента ssh попытается установить tty, используемый stdin, в "сырой" режим, а sshd на удаленном хосте выделит псевдо-tty […], если вы введете Ctrl+C, он будет отправлен на удаленный хост, на котором команда, скорее всего, получит SIGINT […]. Затем удаленный sshd закрывает соединение, и ssh сообщает, что Connection to remotehost closed .

Поэтому используйте:

ssh -t hostname command

и ваша command (не локальная ssh) получит SIGINT при нажатии Ctrl+C.


Это может стать еще интереснее. Сравните ssh + здесь документ - Ctrl + C попадает в удаленную сторону?

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .