使用后台进程运行ssh脚本

时间:2018-04-28 04:15:09

标签: unix ssh

以下是我想要完成的一个简单示例。我正在尝试强制ssh脚本不等待所有子进程在返回之前退出。目的是通过ssh在远程主机上启动守护进程。

test.sh

#!/bin/bash

(
sleep 2 
echo "done"
) &

当我在控制台上运行脚本时,它立即返回,2秒后出现“done”。

当我将脚本作为ssh脚本运行时,ssh命令。似乎要等到所有子进程都终止,直到ssh退出。

ssh示例

$ ssh mike@127.0.0.1 /home/mike/test.sh
(2 seconds)
done

标准终端示例

$ ./test.sh
$ 
(2 seconds)
done

当父/主进程终止时,如何进行ssh返回?

修改

我知道ssh的-f选项可以在后台运行该进程。它使ssh进程和连接在源主机上保持打开状态。就我的目的而言,这是不合适的。

1 个答案:

答案 0 :(得分:1)

ssh mike@127.0.0.1 /home/mike/test.sh

以这种方式运行ssh时,远程ssh服务器将创建一组管道(或socketpairs),它们成为您请求它运行的进程的标准输入,输出和错误,在这种情况下是脚本处理。 ssh服务器不会根据脚本进程退出的时间结束会话。相反,它会在脚本进程的标准输出和标准错误读取和结束文件指示时结束会话。

在您的情况下,脚本进程会创建一个子进程,该进程继承脚本的标准输入,输出和错误。当所有可能的编写器退出或关闭管道末端时,管道(或套接字对)仅返回EOF。只要子进程正在运行并且具有标准输出/错误文件描述符的副本,ssh服务器就不会读取这些描述符上的EOF指示,并且它不会关闭会话。

您可以通过在传递给远程服务器的命令中重定向标准输入和标准输出来解决此问题:

ssh mike@127.0.0.1 '/home/mike/test.sh > /dev/null 2>&1'
(note the quotes are important)

这可以避免将ssh服务器创建的标准输出和标准错误传递给脚本进程或它创建的子进程。

或者,您可以向脚本添加重定向:

#!/bin/bash

(
exec > /dev/null 2>&1
sleep 2 
echo "done"
) &

这会导致脚本的子进程关闭其原始标准输出和标准错误的副本。