用于处理 SSH 连接断开/终止的 Linux 陷阱信号

用于处理 SSH 连接断开/终止的 Linux 陷阱信号

我在 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''",

更新:向 npm 脚本添加强制 tty-t似乎已修复此问题。这令人困惑,因为对于简单脚本情况,我不需要它。也许我在大型脚本中生成了太多子进程(太多了,无法粘贴到这里,除非删除一堆),所以需要一个 tty 来触发清理陷阱。

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

答案1

当你这样做

ssh hostname command

然后Ctrl+ C,您终止本地sshcommand仍在远程端运行,它永远不会收到您的按键。这与 不同-t。请参阅这个答案以供解释。相关片段:

在客户端,ssh将尝试将 stdin 使用的 tty 设置为“原始”模式,并sshd在远程主机上分配一个伪 tty […] 如果您键入Ctrl+ C,它将被发送到远程主机,命令可能会在那里收到SIGINT[…]。然后远程sshd关闭连接并ssh报告Connection to remotehost closed

因此使用:

ssh -t hostname command

当您按下+时,您的command(不是本地的ssh)将得到。SIGINTCtrlC


这可能会变得更加有趣。比较ssh + 此处文档 – Ctrl+C 能到达远端吗?

相关内容