我有一个由两部分组成的脚本。第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 连接到达脚本末尾时强制退出。
我已经尝试过了exit
,exit 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"