LVL*_*ron 59 scripting ssh nohup background-process
我有两台电脑,localpc
和remoteserver
。
我需要localpc
在remoteserver
. 它需要做的一件事是启动一个运行数小时的备份脚本。我希望命令localpc
“开火”然后完全独立运行remoteserver
,就像一localpc
开始就不存在一样。
这是我到目前为止所做的:
remoteserver
包含有脚本:
/root/backup.sh
Run Code Online (Sandbox Code Playgroud)
localpc
计划运行这个:
ssh root@remoteserver 'nohup /root/backup.sh' &
Run Code Online (Sandbox Code Playgroud)
我这样做是否正确?有一个更好的方法吗?这样做我会遇到任何麻烦吗?
Gil*_*il' 59
关闭,但不完全是。
ssh root@remoteserver '/root/backup.sh </dev/null >/var/log/root-backup.log 2>&1 &'
Run Code Online (Sandbox Code Playgroud)
您需要关闭所有连接到 ssh 套接字的文件描述符,因为只要某个远程进程打开了套接字,ssh 会话就不会关闭。如果您对脚本的输出不感兴趣(大概是因为脚本本身负责写入日志文件),请将其重定向到/dev/null
(但请注意,这将隐藏诸如无法启动脚本之类的错误)。
使用nohup
在这里没有任何有用的效果。nohup
如果程序的控制终端消失,它会安排它运行的程序不接收 HUP 信号,但这里首先没有终端,所以没有什么会突然向进程发送 SIGHUP 信号。此外,nohup
将标准输出和标准错误(但不是标准输入)重定向到文件,但前提是它们连接到终端,同样,它们不是。
aaron@localpc$ ssh root@remoteserver
root@remoteserver# nohup /root/backup.sh </dev/null &
nohup: appending output to `nohup.out'
[1] 12345
root@remoteserver# exit
aaron@localpc$
Run Code Online (Sandbox Code Playgroud)
使用nohup
从它的控制终端,从而脱离脚本,它并没有收到SIGHUP当终端消失。nohup
还将脚本的标准输出和标准错误重定向到一个文件,nohup.out
如果它们连接到终端则调用;你必须自己处理标准输入。
如果您想让命令在远程终端中运行但不将其附加到 SSH 会话,请在终端多路复用器中运行它,例如Screen或Tmux。
ssh root@remoteserver 'screen -S backup -d -m /root/backup.sh'
Run Code Online (Sandbox Code Playgroud)
您可以稍后通过screen -S backup -rd
在该机器上以 root 身份调用来重新连接到运行脚本的终端。
为了稍微提高安全性,不要太广泛地打开直接远程 root 登录。创建一个特殊用途的密钥对,并在/root/.ssh/authorized_keys
. 公钥文件的内容是AAAA…== wibble@example.com
; 添加以逗号分隔的选项列表,其中包括command="…"
指定密钥只能用于执行此特定命令的选项。确保将选项和键都放在一行上。
command="/root/backup.sh </dev/null >/dev/null 2>/dev/null &",no-port-forwarding,no-agent-forwarding,no-x11-forwarding,no-pty,no-user-rc AAAA…== wibble@example.com
Run Code Online (Sandbox Code Playgroud)
enz*_*tib 51
您可能应该screen
在远程主机上使用,以获得真正的分离命令:
ssh root@remoteserver screen -d -m ./script
Run Code Online (Sandbox Code Playgroud)
Mic*_*lon 13
从远程登录(如 SSH)运行远程命令的标准方法如下:
nohup command </dev/null >command.log 2>&1 &
Run Code Online (Sandbox Code Playgroud)
如果command
是一个负责记录到文件本身的 shell 脚本,那么您可以更改command.log
为/dev/null
. 开始此操作后,请立即注销。
你需要那条线上的一切。
nohup
如果登录会话断开连接,则告诉 shell 不要打扰进程。
</dev/null
告诉它永远不要等待输入
>command.log
告诉它向这个命名的日志文件发送任何消息
2>&1
告诉它发送任何 stderr 消息到同一个日志文件。在某些情况下,最好有两个文件,第二个用于收集错误消息,第一个用于收集正常活动消息。这可以更容易地验证一切是否正常工作。
&
告诉它分离这个进程并作为守护进程在后台运行。
小智 12
该线程非常有帮助,但我的解决方案必须有所不同。
我不喜欢屏幕解决方案,因为它会留下我不需要的屏幕进程。重定向和 nohups 使用如下:
ssh root@remoteserver '/root/backup.sh </dev/null >/var/log/root-backup.log 2>&1 &'
Run Code Online (Sandbox Code Playgroud)
与 ssh 命令一起使用时对我不起作用。
我在运行实际脚本的远程机器上创建了一个包装脚本。包装器脚本设置重定向和 nohup。像这样的东西:
backupwrapper.sh:
nohup backup.sh > /dev/null 2>&1 &
Run Code Online (Sandbox Code Playgroud)
然后在我的客户端机器上运行(注意没有重定向):
# ssh remotemachine "backupwrapper.sh"
#
Run Code Online (Sandbox Code Playgroud)
ssh 命令立即返回,连接终止,脚本继续运行。
小智 7
正如Nils 所说,允许 root 通过 ssh 登录存在安全风险。我建议不要在没有日志的机器上运行任何实质性的工作。如果出现任何问题,您会希望收到一些故障排除消息。还有其他答案向您展示了如何做到这一点。但这是我建议完成您所要求的方法。这一切都内置在 sh(1) 中。不需要 GNU 屏幕(虽然我认为这是一个聪明的解决方案)。将此字符串附加到您的命令:>&- 2>&- <&- &
。>&-
意味着关闭标准输出。2>&-
意味着关闭标准错误。<&-
意味着关闭标准输入。&
意味着在后台运行,例如
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
169545 次 |
最近记录: |