Sudo - 等待子进程并获取子进程PID

3
似乎在sudo 1.7.2p2和1.7.4p5之间,等待执行进程的行为发生了变化。看起来在旧版本中,sudo会启动新进程,然后退出。而在新版本中,它启动新进程,等待新进程结束。这里有一些关于它的讨论:http://www.sudo.ws/pipermail/sudo-users/2010-August/004461.html,其中提到它是为了防止破坏PAM会话支持。
这个改变正在破坏我的一个脚本,该脚本使用sudo在后台执行命令,因为旧版本sudo执行我想要执行的命令会被放入后台,而新版本中则是sudo自身被放入后台。
例如,在此情况下返回的进程是sleep
user@localhost$ sudo -V
Sudo version 1.7.2p2
user@localhost$ sudo -u poweruser sleep 60 &
[1] 17491
user@localhost$ ps -fp $!
UID        PID  PPID  C STIME TTY          TIME CMD
poweruser 17491 17392  0 16:43 pts/0    00:00:00 sleep 60

在这种情况下,它是用于sudo

user@localhost$ sudo -V
Sudo version 1.7.4p5
user@localhost$ sudo -u poweruser sleep 60 &
[1] 792
user@localhost$ ps -fp $!
UID        PID  PPID  C STIME TTY          TIME CMD
root       792 29257  0 16:42 pts/3    00:00:00 sudo -u poweruser sleep 60

在sudo版本1.7.4p5中,是否有可能获取由其执行的子进程的进程ID?$!变量返回sudo的PID,并且使用-b选项运行sudo似乎不能使子PID可用。是否有可能(无需重新编译sudo)恢复sudo的行为,以防止其等待子进程?

谢谢

1个回答

1

这肯定是一种黑客方式,它不会设置 $!,但你可以回显命令的 pid:

$ sudo sh -c 'echo $$; exec sleep 60'

我猜你对旧行为的解释可能不太正确,sudo 只是执行了命令而不是分叉和退出。回显 pid 然后执行所需的命令可能适用于你,但你可能需要进行创造性的重定向。例如:

#!/bin/sh
exec 3>&1 pid=$( sudo sh -c 'echo $$; exec sh -c "{ sleep 1; echo my pid is $$; }" >&3 &') echo Child pid is $pid

在上面的例子中,你失去了 sudo 的 pid...但找到它并不难。


谢谢William。实际上我只需要将pid存储在一个文件中,所以我的重定向并不是很有创意。最终我得到了这样的东西:sudo -u poweruser sh -c "echo \$\$ > ${pid_file}; exec sleep 60" & - nickelaway
嗨,我尝试了你的代码,但一直收到“sh: 1: 3: Bad file descriptor”错误。我做错了什么? - Frederick Behrends
@Frederick 如果没有提供 exec,或者使用了 exec 1>&3 命令,都可能导致您所描述的错误。 - William Pursell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接