终止由bash脚本执行的SSH会话

我有一个脚本,我可以在本地运行远程启动服务器:

#!/bin/bash
ssh user@host.com <<EOF
  nohup /path/to/run.sh &
EOF
echo 'done'

运行nohup后,它挂起。 我必须按ctrl-c才能退出脚本。

我试过在这里的文档的末尾添加一个明确的退出,并使用“-t”作为ssh的参数。 两者都不起作用。 我如何让这个脚本立即退出?

编辑:客户端是OSX 10.6,服务器是Ubuntu。


我认为问题在于,当你从ssh进入时nohup不能重定向输出,它只在它认为连接到终端时重定向到nohup.out,而且我拥有的stdin覆盖将会阻止,即使使用-t

解决方法可能是自己重定向输出,然后SSH客户端可以断开连接 - 它不会等待流关闭。 就像是:

nohup /path/to/run.sh > run.log &

(这对我来说是一个简单的测试,从OS X客户端连接到Ubuntu服务器。)


问题可能是...

... ssh is respecting the POSIX standard when not closing the session 
if a process is still attached to the tty.

因此,解决方案可能是从tty分离nohup命令的stdin

nohup /path/to/run.sh </dev/null &

请参阅:使用nohup时,SSH在退出时挂起

另一种方法可能是使用ssh -t -t来强制伪tty分配,即使stdin不是终端。

man ssh | less -Ip 'multiple -t'

ssh -t -t user@host.com <<EOF
  nohup /path/to/run.sh &
EOF

请参阅:用于SSH的BASH spawn subshel​​l,并继续执行程序流程


在不使用显式命令的情况下调用ssh ,将来自here文档的远程主机的stdin重定向会导致消息: Pseudo-terminal will not be allocated because stdin is not a terminal.

要避免这个消息,可以使用ssh-T switch来告诉远程主机,不需要分配一个伪终端,或者为远程主机明确指定一个命令(比如/bin/sh )来执行命令这里的文件。

如果显式命令给予ssh ,默认是提供以伪终端的形式没有登录的外壳,即,将不会有正常登录会话中指定的命令时(见man ssh )。

另一方面,如果没有为ssh指定命令,则缺省情况是为远程主机上的交互式登录会话创建伪tty。

- ssh user@host.com <<EOF
+ ssh -T user@host.com <<EOF
+ ssh user@host.com /bin/bash <<EOF

通常,只有在命令需要stdin / stdout成为终端(如topvim )或需要终止远程shell及其终端时才使用ssh -tssh -t -tssh客户端命令完成执行时(参见:在ssh终止后,ssh命令意外地继续在其他系统上)的子节点。

据我所知,结合不分配伪tty的ssh命令和在远程主机上写入nohup.outnohup命令的唯一方法是让nohup命令在伪终端中执行, 而不是ssh机制创建。 例如,可以使用script命令完成此操作,并避免tcgetattr: Inappropriate ioctl for device消息的tcgetattr: Inappropriate ioctl for device

#!/bin/bash
ssh localhost /bin/sh <<EOF
  #0<&-  script -q /dev/null nohup sleep 10 1>&- &
  #0<&- script -q -c "nohup sh -c 'date; sleep 10 1>&- &'" /dev/null  # Linux
  0<&- script -q /dev/null nohup sh -c 'date; sleep 10 1>&- &'        # FreeBSD, Mac OS X
  cat nohup.out
  exit 0
EOF
echo 'done'
exit 0
链接地址: http://www.djcxy.com/p/97123.html

上一篇: Terminating SSH session executed by bash script

下一篇: Find`s placeholder {} sed from variable1 and put into variable2