终止由 bash 脚本执行的 SSH 会话
我有一个可以在本地运行以远程启动服务器的脚本:
#!/bin/bash
ssh [email protected] <<EOF
nohup /path/to/run.sh &
EOF
echo 'done'
运行 nohup 后,它挂起。我必须按 ctrl-c 才能退出脚本。
我尝试在此处文档的末尾添加显式退出,并使用 ssh 的“-t”参数。两者都不起作用。如何让这个脚本立即退出?
编辑:客户端是OSX 10.6,服务器是Ubuntu。
I have a script I can run locally to remotely start a server:
#!/bin/bash
ssh [email protected] <<EOF
nohup /path/to/run.sh &
EOF
echo 'done'
After running nohup, it hangs. I have to hit ctrl-c to exit the script.
I've tried adding an explicit exit at the end of the here doc and using "-t" argument for ssh. Neither works. How do I make this script exit immediately?
EDIT: The client is OSX 10.6, server is Ubuntu.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我认为问题是,当您从 ssh 进入时,nohup 无法重定向输出,它仅在认为已连接到终端时重定向到 nohup.out,并且我的 stdin 覆盖会阻止这种情况,即使使用
-t
。解决方法可能是自己重定向输出,然后 ssh 客户端可以断开连接 - 它不会等待流关闭。类似于:
(这对我来说是一个从 OS X 客户端连接到 Ubuntu 服务器的简单测试。)
I think the problem is that nohup can't redirect output when you come in from ssh, it only redirects to nohup.out when it thinks it's connected to a terminal, and I the stdin override you have will prevent that, even with
-t
.A workaround might be to redirect the output yourself, then the ssh client can disconnect - it's not waiting for the stream to close. Something like:
(This worked for me in a simple test connecting to an Ubuntu server from an OS X client.)
问题可能是......
因此,解决方案可能是将
nohup
命令的stdin
与 tty 分离:请参阅:使用 nohup 时 SSH 在退出时挂起
另一种方法可能即使
stdin
不是终端,也可以使用 ssh -t -t 强制伪 tty 分配。请参阅:BASH 生成 SSH 的子 shell 并继续程序流程
The problem might be that ...
Therefore a solution might be to detach the
stdin
of thenohup
command from the tty:See: SSH Hangs On Exit When Using nohup
Yet another approach might be to use
ssh -t -t
to force pseudo-tty allocation even ifstdin
isn't a terminal.See: BASH spawn subshell for SSH and continue with program flow
在没有显式命令的情况下调用 ssh 时从此处文档重定向远程主机的标准输入会导致消息:
伪终端将不会被分配,因为标准输入不是终端。
要避免此消息,请使用
ssh
的-T
开关告诉远程主机无需分配伪终端或显式指定命令(例如<代码>/bin/sh)让远程主机执行此处文档提供的命令。如果给
ssh
明确的命令,则默认以伪终端的形式提供no登录shell,即当指定命令(请参阅man ssh
)。另一方面,如果没有为
ssh
指定命令,则默认情况下会在远程主机上为交互式登录会话创建伪 tty。通常,仅当存在期望 stdin / stdout 成为终端的命令(例如
ssh -t -t
>top 或vim
),或者是否需要在 ssh 客户端命令完成执行时终止远程 shell 及其子级(请参阅:ssh 命令在 ssh 终止后意外地在其他系统上继续运行)。据我所知,结合不分配伪tty的 ssh 命令和写入 nohup.out 的 nohup 命令的唯一方法在远程主机上的作用是让
nohup
命令在非由ssh
机制创建的伪终端中执行。例如,这可以使用script
命令来完成,并且将避免出现tcgetattr:不适当的 ioctl for device
消息。Redirecting the stdin of the remote host from a here document while invoking
ssh
without an explicit command leads to the message:Pseudo-terminal will not be allocated because stdin is not a terminal.
To avoid this message either use
ssh
's-T
switch to tell the remote host there is no need to allocate a pseudo-terminal or explicitly specify a command (such as/bin/sh
) for the remote host to execute the commands provided by the here document.If an explicit command is given to
ssh
, the default is to provide no login shell in the form of a pseudo-terminal, i. e. there will be no normal login session when a command is specified (seeman ssh
).Without a command specified for
ssh
, on the other hand, the default is to create a pseudo-tty for an interactive login session on the remote host.As a rule,
ssh -t
or evenssh -t -t
should only be used if there are commands that expect stdin / stdout to be a terminal (such astop
orvim
) or if it is necessary to kill the remote shell and its children when thessh
client command finishes execution (see: ssh command unexpectedly continues on other system after ssh terminates).As far as I can tell, the only way to combine an
ssh
command that does not allocate a pseudo-tty and anohup
command that writes tonohup.out
on the remote host is to let thenohup
command execute in a pseudo-terminal not created by thessh
mechanism. This can be done with thescript
command, for example, and will avoid thetcgetattr: Inappropriate ioctl for device
message.您需要在末尾添加
exit 0
。You need to add a
exit 0
at the end.