这是关于如何在shell脚本中使用ssh的后续问题?题.如果我想在该机器的后台运行的远程机器上执行命令,我该如何获取ssh命令?当我尝试在命令末尾包含&符号时,它就会挂起.命令的确切形式如下所示:
ssh user@target "cd /some/directory; program-to-execute &"
有任何想法吗?需要注意的一点是,登录目标计算机始终会生成文本标题,并且我已设置SSH密钥,因此无需密码.
我在一年前写的一个程序中遇到了这个问题 - 事实证明答案相当复杂.您需要使用nohup以及输出重定向,如nohup上的维基百科artcle中所述,为方便起见,将其复制到此处.
例如,当通过SSH登录时,Nohuping后台作业很有用,因为后台作业可能会因为竞争条件导致shell挂起[2].通过重定向所有三个I/O流也可以克服此问题:
nohup myprogram > foo.out 2> foo.err < /dev/null &
这对我来说是最干净的方式: -
ssh -n -f user@host "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"
在此之后运行的唯一事情是远程计算机上的实际命令
需要重定向输出&>/dev/null
,将stderr和stdout重定向到/ dev/null并且是>/dev/null 2>/dev/null
或的同义词>/dev/null 2>&1
.
最好的方法是使用sh -c '( ( command ) & )'
命令是什么.
ssh askapache 'sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
您也可以直接使用nohup来启动shell:
ssh askapache 'nohup sh -c "( ( chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
另一个技巧是使用nice来启动命令/ shell:
ssh askapache 'nice -n 19 sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
如果您没有/不能保持连接打开,您可以使用屏幕,如果您有权安装它.
user@localhost $ screen -t remote-command user@localhost $ ssh user@target # now inside of a screen session user@remotehost $ cd /some/directory; program-to-execute &
要分离屏幕会话: ctrl-a d
列出屏幕会话:
screen -ls
要重新连接会话:
screen -d -r remote-command
请注意,屏幕还可以在每个会话中创建多个shell.使用tmux可以实现类似的效果.
user@localhost $ tmux user@localhost $ ssh user@target # now inside of a tmux session user@remotehost $ cd /some/directory; program-to-execute &
要分离tmux会话: ctrl-b d
列出屏幕会话:
tmux list-sessions
要重新连接会话:
tmux attach
默认的tmux控制键' ctrl-b'有点难以使用,但有几个示例tmux配置随tmux一起提供,您可以尝试.
我只是想展示一个可以剪切和粘贴的工作示例:
ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /dev/null &\""
最快捷最简单的方法是使用'at'命令:
ssh user @ target"at now -f /home/foo.sh"
我想你必须将这些答案结合起来才能得到你想要的东西.如果你将nohup与分号结合使用,并将整个内容包装在引号中,那么你得到:
ssh user@target "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"
这似乎对我有用.使用nohup,您无需将&附加到要运行的命令.此外,如果您不需要读取命令的任何输出,则可以使用
ssh user@target "cd /some/directory; nohup myprogram > /dev/null 2>&1"
将所有输出重定向到/ dev/null.
这对我来说有用时间:
ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh /dev/null 2>&1 & "