似乎在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的行为以阻止它等待子进程?
由于
答案 0 :(得分: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 ......但是找到它并不会太难。