如何强制 ssh 连接在脚本结束时退出

如何强制 ssh 连接在脚本结束时退出

我有一个由两部分组成的脚本。第1部分创建一个 ssh 连接,第2部分运行一个脚本(大约 800 行,到目前为止还在增加)。

part1:
ssh $target_server "bash -s" < $target_script

问题是第2部分包含以下几行:

fc_START_WINE_APP () { nohup `DISPLAY=:11.0 wine "$1"` & }
. . .
fc_START_WINE_APP $applicationFull

基本上,它检查应用程序是否正在运行,如果没有则重新启动它(以及其他一些东西)。

问题是,当该函数执行到start应用程序时,会导致 ssh 连接挂起。

有没有办法在 ssh 连接到达脚本末尾时强制退出。

我已经尝试过了exitexit 0等等exit 1第2部分。我尝试ssh -f第1部分但是之后第2部分似乎没有执行。


更新2016-01-28

一个例子如下

**SCRIPT1**
#!/bin/bash

target_server="1.2.3.4"
target_script="/home/user/script2.sh"

echo "Script 1 Started"

ssh $target_server "bash -s" < $target_script

echo "Script 1 Ended"

**SCRIPT 2**
#!/bin/bash

echo "Script 2 Started"

fc_START_WINE_APP () { nohup `DISPLAY=:11.0 wine "$1"` & }

applicationFull="/home/tech/myApp.exe"

fc_START_WINE_APP $applicationFull

echo "Script 2 Ended"

运行此命令时,它会到达Script 2 Ended,但不会关闭 ssh 连接,因此永远不会到达Script 1 Ended

您可能知道,该脚本的要点是连接到给定服务器,并使用 Wine 启动一个(旧 Windows)应用程序。

我的理解是,必须nohup . . &在 ssh 连接关闭时启动它来停止应用程序关闭,就像我直接登录(例如使用 putty)、运行nohup myCommand &然后退出,然后myCommmand仍然运行一样。

答案1

分离程序时,您应该将两个输出重定向到某处(到 /dev/null 或日志文件),并使用:

&>/dev/null &                         ...when bash --version >= 4

或者

>/dev/null 2>&1 &                     ...all shells

而不仅仅是:

&

...这样启动ssh就不需要担心stdout、stderr并且可以退出。

nohup 并不总是很重要(取决于 shell 配置和程序的 hup 信号处理...,在我的测试中:'sleep'、'xclock' 和 'wine notepad.exe' 无需 nohup 即可继续工作)。在需要 nohup 的情况下,通常 screen 和 tmux 是更好的解决方案。

假设 bash>=4,测试分离行为的最小示例是:

ssh 1.2.3.4 "sleep 10 &"               ... exits after 10 seconds
ssh 1.2.3.4 "sleep 10 &>/dev/null &"   ... exits immediately

在您的特定 script1/2 情况下, script2 中的函数 fc_START_WINE_APP 应为:

{ DISPLAY=:11.0 wine "$1" &>/dev/null & }

...对于 $1 值“notepad.exe”效果很好...但是如果您出于某种原因仍然需要 nohup,它只接受一个命令,而您有 2 个命令(设置显示并运行 wine),因此您必须将其包装在里面重击:

{ nohup bash -c "DISPLAY=:11.0 wine $1" &>/dev/null & }

答案2

我想我已经找到了做到这一点的方法:

part1:
ssh $target_server "bash -s" < $target_script > logfile.log 2> logfile.err &

这样,主脚本会立即完成,而第二个脚本则在后台运行。

答案3

您的 ssh 会话需要一个控制终端,用于该用途ssh -t

另外,您可以part2直接从 ssh 执行。所以第 1 部分看起来像这样:

**SCRIPT1**
#!/bin/bash

target_server="1.2.3.4"
target_script="/home/user/script2.sh"

echo "Script 1 Started"

scp $target_script $target_server:/tmp/my_script_part2.sh
ssh -t $target_server /tmp/my_script_part2.sh
ssh $target_server rm -f /tmp/my_script_part2.sh

echo "Script 1 Ended"

相关内容