这可能会被回答通过 ssh 继续运行脚本,如果我不必以超级用户身份运行命令。让我尝试举个例子:假设在我的服务器上,我有这个脚本~/testsleep.sh
,它也是chmod +x
:
#!/usr/bin/env bash
logger Pre sleep: "$USER" / "$USERNAME" / "$1"
sleep 5
logger Post sleep: "$USER" / "$USERNAME" / "$1"
我想要logger
登录/var/log/syslog
,因为通过ssh
我可能会丢失标准输出/标准错误。
ssh
假设我在本地 PC 上运行此程序,并通过远程服务器登录:
server$ readlink -f ~/testsleep.sh
/home/user/testsleep.sh
server$ $ ls -la testsleep.sh
-rwxr-xr-x 1 user user 126 2015-02-05 13:35 testsleep.sh
server$ sudo /home/user/testsleep.sh some_argument
sudo: unable to execute /home/user/testsleep.sh: No such file or directory
第一个问题是我无法直接使用 运行脚本sudo
,即使它是可执行的;我认为这与“您当前的 shell 正在您的常规用户 ID 下运行...并且无法授予它 root 访问权限”在具有 sudo 权限的当前 shell 中执行 shell 脚本_shell_帮酷编程问答
好吧,好吧,我会运行sudo bash
- 这看起来更像是这样:
server$ sudo bash /home/user/testsleep.sh some_argument
server$ tail -2 /var/log/syslog
Feb 5 13:40:48 user user: Pre sleep: root / root / some_argument
Feb 5 13:40:53 user user: Post sleep: root / root / some_argument
因此,显然该脚本确实登录了syslog
,并且显示root
为$USER
;如预期。到目前为止,一切都很好。
现在,我想在退出ssh
终端会话之前将此脚本作为服务器上的进程运行。我想我会这样做:
server$ sudo bash /home/user/testsleep.sh from_end & exit
[1] 6293
logout
Connection to 127.1.100.99 closed.
local$
如果我重新登录服务器并syslog
再次检查,我可以看到最后一次“退出”调用没有日志:
# this `grep` will print the filename, if file doesn't contain the match:
server$ grep --files-without-match 'from_end' /var/log/syslog
/var/log/syslog
server$ tail -2 /var/log/syslog
Feb 5 13:40:48 mypc user: Pre sleep: root / root / some_argument
Feb 5 13:40:53 mypc user: Post sleep: root / root / some_argument
所以,我的问题是 - 如何在服务器上的 sudo 下将此脚本作为进程运行 - 但从ssh
shell 调用,并在退出之前;以便它运行(在本例中,通过写入 来确认syslog
)?
答案1
您需要disown
这项工作,以便在连接“挂断”时它不会被终止:
sudo bash /home/user/testsleep.sh from_end & sleep 1; disown -h; exit
它的sleep 1
作用是减少后台作业启动和 shell 退出之间的竞争。如果您可以避免在一行中完成所有操作,则将两组命令分开会得到更好的结果:
sudo bash /home/user/testsleep.sh from_end &
disown -h; exit