在目标机器上使ssh在后台执行命令。
在目标机器上使ssh在后台执行命令。
这是对如何在Shell脚本中使用ssh?问题的后续问题。如果我想在远程机器上执行一个在该机器上后台运行的命令,如何使ssh命令返回?当我尝试在命令的末尾加上&符号时,它就会一直挂起。命令的确切形式如下:
ssh user@target "cd /some/directory; program-to-execute &"
有什么想法吗?需要注意的一点是,登录到目标机器总是会产生一个文本横幅,而且我已经设置了SSH密钥,不需要密码。
问题出现的原因是需要在目标机器上执行一个命令,但希望该命令在后台运行。解决方法是使用ssh命令,通过在命令中添加特定的参数来实现在目标机器上执行命令并使其在后台运行。
以下是解决方法的具体步骤:
1. 在本地机器上,使用以下命令来通过ssh连接到目标机器并执行命令:
ssh -n -f user "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"
这里的`user`是目标机器上的用户名,`/whereever`是目标机器上命令需要执行的目录,`./whatever`是要执行的命令。通过将命令放在`nohup`命令的后面,并将输出重定向到`/dev/null`,可以使命令在后台运行并且不会在终端上显示输出。
2. 可以省略`-n`参数,因为`-f`参数已经隐含了`-n`参数的作用。`-f`参数使得ssh进程在后台运行,而不会阻塞终端。
3. 如果希望ssh连接快速断开,可以使用`/dev/null`来重定向输出。这样ssh连接会立即断开,而不会等待命令执行完毕。
4. 如果需要在Syonology NAS上发送命令,以上方法同样适用。
5. 如果希望在远程机器上显示命令的输出,可以将重定向输出到一个指定的文件,而不是`/dev/null`。
6. 在OpenWrt系统上,默认情况下没有安装`nohup`命令,但可以使用以下命令实现相同的效果:
ssh user "sh -c 'command1; command2' >/dev/null 2>&1
这里的`command1`和`command2`是要执行的命令。
通过以上方法,可以在目标机器上执行命令并使其在后台运行。
在目标机器上执行后台命令的问题:原因是在通过SSH登录时,后台作业可能导致shell在注销时挂起,解决方法是使用nohup
命令将命令移至后台,并将输出重定向到日志文件中,使用< /dev/null
将EOF发送给程序,以避免等待输入。
以下是解决方法的示例代码:
nohup myprogram > foo.log 2> foo.err < /dev/null &
这个命令将后台作业移至后台,并将标准输出和标准错误输出重定向到foo.log
和foo.err
文件中,同时不等待任何输入。
< /dev/null
将EOF发送给程序,以避免等待输入。其中/dev/null
是一个特殊文件,它会丢弃所有写入它的数据,并报告写入操作成功,对从它读取的任何进程提供没有数据的EOF。
&
用于将命令移至后台执行。这样即使连接丢失或注销,命令也会继续运行。
关于< /dev/null
的更多解释可以在这个答案中找到。
此外,维基百科的文章中也有相关信息。在通过SSH登录时,后台作业可能导致shell在注销时挂起,这个问题也可以通过重定向所有三个I/O流来解决。
以上是解决这个问题的原因和方法的整理。
问题的原因是需要在目标机器上执行一个后台命令,但是直接使用ssh命令执行命令时,命令会在前台执行,无法后台执行。解决这个问题的方法有几种。
第一种方法是重定向输出到/dev/null,可以使用以下命令:>/dev/null 2>&1
或者>/dev/null 2>/dev/null
。这样可以将标准输出和标准错误都重定向到/dev/null,实现后台执行。
第二种方法是使用括号的方式,可以使用以下命令:sh -c '( ( command ) & )'
,其中command可以是任何命令。这种方式也可以实现后台执行。
第三种方法是直接使用nohup命令来启动shell,可以使用以下命令:nohup sh -c "( ( command ) & )"
。这样可以在后台执行命令,并且不需要在命令末尾添加&。
第四种方法是使用nice命令来启动命令或shell,可以使用以下命令:nice -n 19 sh -c "( ( command ) & )"
。这样可以以较低的优先级执行命令或shell。
关于为什么括号方式是最佳方式、添加nohup的作用以及使用nice的原因和时机,这些问题的答案没有在给出的内容中提到。