【问题标题】:Sudo - Waiting for child, and getting child PIDSudo - 等待孩子,并获得孩子 PID
【发布时间】:2012-03-07 01:05:57
【问题描述】:

似乎在 sudo 1.7.2p2 和 1.7.4p5 之间的某个地方,等待执行进程的行为发生了变化。看起来在旧版本中 sudo 会启动新进程,然后退出。在较新的版本中,它启动新进程,然后等待它。这里有一些关于它的讨论:http://www.sudo.ws/pipermail/sudo-users/2010-August/004461.html 提到它是为了阻止它破坏 PAM 会话支持。

此更改破坏了我使用 sudo 在后台执行命令的脚本之一,因为对于旧版本 sudo,我要执行的命令将在后台运行,而在新版本中,sudo 本身是后台运行的。

例如 $! 返回的进程在这种情况下是为了睡眠

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 的行为以阻止它等待子进程?

谢谢

【问题讨论】:

    标签: linux bash background process sudo


    【解决方案1】:

    这肯定是个 hack,它没有设置 $!,但是你可以 echo 命令的 pid:

    $ sudo sh -c '回声 $$;执行睡眠 60'

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

    #!/bin/sh 执行 3>&1 pid=$( sudo sh -c 'echo $$; exec sh -c "{ sleep 1; 回显我的 pid 是 $$; }" >&3 &') echo 子 pid 是 $pid

    在上面,你丢失了 sudo 的 pid...但它不会太难找到它。

    【讨论】:

    • 谢谢威廉。我实际上只需要将 pid 存储在一个文件中,所以我的重定向并不是那么有创意。我最终得到了这样的结果:sudo -u poweruser sh -c "echo \$\$ > ${pid_file}; exec sleep 60" &
    • 嗨,尝试了您的代码,但我不断收到sh: 1: 3: Bad file descriptor 错误。我做错了什么?
    • @Frederick exec 1>&3 可能会给出您描述的错误,因为无法提供 exec
    猜你喜欢
    • 2016-11-30
    • 2021-04-28
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 2021-02-16
    相关资源
    最近更新 更多