Linux陷阱信号处理SSH连接丢弃/被杀死


3

我在一个npm脚本中有一个命令,它连接到一个远程构建服务器并运行一个Bash脚本。该脚本设置了一个锁文件和一个 trap 调用在脚本退出时删除lockfile。

我正在取消该操作 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
您可能需要为其添加完整的二进制路径 touchtrap。常见问题。也, 看看我建议在这个答案中使用的Bash脚本 处理PID锁定逻辑以避免Bash脚本在其自身上运行。
JakeGould

Answers:


2

当你这样做

ssh hostname command

然后 按Ctrl + C ,你终止本地 ssh。该 command 仍然在远程运行,它永远不会让你的击键。这与之不同 -t。看到 这个答案 作出解释。相关片段:

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

因此使用:

ssh -t hostname command

和你的 command (不是当地的 ssh )会得到 SIGINT 当你按下 按Ctrl + C


这可能会变得更有趣。相比 ssh + here document - Ctrl + C到远程端吗?


这是我在实践中看到的,但是ctrl-c确实停止执行远程主机命令。或者这只是一个暂时的延续,当它丢失插座或其他东西时会退出?记录输出立即停止,因此它获得某种SIG。
Brian

另外,我不需要-t用于上面链接的简单脚本。所以它有微妙之处。
Brian

1
@Brian我不确定。我怀疑它可能与某些事情有关 stdin 或者。在我的测试遥控器 sleep 在当地生存 ssh 退出,但远程 cat 退出。它们中的每一个都在Ctrl + C时退出 -t 用来。
Kamil Maciorowski
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.