通过 ssh 在服务器上以 sudo 身份运行“预定”/延迟脚本 - 在 ssh 退出之前

通过 ssh 在服务器上以 sudo 身份运行“预定”/延迟脚本 - 在 ssh 退出之前

这可能会被回答通过 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 下将此脚本作为进程运行 - 但从sshshell 调用,并在退出之前;以便它运行(在本例中,通过写入 来确认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

相关内容