我想在远程服务器中运行一个长时间运行的命令,即使在连接终止后也是如此。所以我想到使用ssh host "nohup cmd &"
。但由于某种原因,cmd 既不会进入后台,也不会将其输出重定向到 nohup.out。一切都像我刚刚运行一样发生ssh host cmd
。
user@ubuntu:~$ ssh utubuntu16x64-1 "nohup ls &"
bin
scripts
views
workflows
user@ubuntu:~$ ssh utubuntu16x64-1 "ls"
bin
scripts
views
workflows
我尝试nohup cmd &
直接在远程机器上运行命令,它运行正常。我不明白错误在哪里。
答案1
这规范nohup
状态[强调我的]:
如果标准输入与终端相关联,
nohup
效用可能从未指定的文件重定向标准输入。如果标准输出是终端,指定实用程序写入其标准输出的所有输出将
nohup.out
附加到当前目录中文件的末尾。 […]如果标准错误是终端并且标准输出已打开但不是终端,则指定实用程序的所有输出都写入其标准错误将重定向到与标准输出相同的打开文件描述。如果标准错误是终端标准输出要么是终端,要么是关闭的,输出相同将而是像上面描述的那样附加到文件末尾
nohup.out
。
尽管它没有指定nohup
针对指向非终端的标准 I/O 流的行为,但合理的预期是nohup
应保持它们原样。nohup
如果是终端,则重定向标准 I/O 流,如果是其他任何流,则不重定向。 的工作nohup
由两部分组成:
- 忽略 SIGHUP,
- 重定向远离终端。
您ssh utubuntu16x64-1 "nohup ls &"
没有在远程端分配终端。标准 I/O 流是将远程命令连接到本地相应 I/O 流的管道ssh
(本例中 stdin 除外,请继续阅读)。它们都不是终端,因此nohup
不会重定向它们。
至少有两种方法可以重定向到 (远程) nohup.out
:
在远端分配一个tty:
ssh -t utubuntu16x64-1 "nohup ls &"
(如果本地标准输入不是终端,那么您需要
-tt
。)但可能会有副作用(例如本地消息说Connection to utubuntu16x64-1 closed.
)。手动重定向:
ssh utubuntu16x64-1 "nohup ls >nohup.out 2>&1 &"
注意“可以”不同于“应当”。即使远程标准输入是终端,nohup
也可能会或可能不会将其重定向。一般来说,不重定向输入可能会有所不同,但在这里&
将 stdin 分配给/dev/null
(或等效文件)首先,所以nohup
发现它的标准输入无论如何都没有与终端关联。
两种方法均应让当地人ssh
无需等待。
我尝试
nohup cmd &
直接在远程机器上运行命令,并且它运行正常。
“直接”或在ssh utubuntu16x64
您处于交互式 shell 中并且为其分配了 tty 之后,所有标准 I/O 流都与 tty 相关联。这就是您nohup
按预期工作的原因。
答案2
nohup
期望没有输出到 stdout 和 stderr 以便能够通过 ssh 在后台运行。
对于您来说,正确的语法如下:
ssh user@host "nohup cmd > nohup.out 2>&1 &"