zenity --auto-kill:杀死一个子shell不会杀死它的子进程?

时间:2017-06-17 17:22:11

标签: shell kill subshell zenity

我很难理解zenity --progress --auto-kill的行为。它似乎不会杀死它的父进程的子进程,而是以某种方式分离它们。

考虑以下shell脚本long-live-the-subshell.sh

#!/bin/sh
(
    echo sleeping...>&2;
    sleep 5;
    echo woke up >&2 
)  | zenity --progress --auto-close --auto-kill

重现上述行为:

  • 执行脚本sh long-live-the-subshell.sh
  • 点击进度条
  • 上的取消
  • 再等5秒
  • 看到woke up输出到终端

示例输出:

> sh long-live-the-subshell.sh 
sleeping...
Hangup
> woke up

单击取消时会发生Hangup。然后你得到你的提示。但是,在sleep 5完成后,woke up将输出到终端。

运行脚本后立即

ps jf

 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
20806 20825 20825 20825 pts/7     2391 Ss    1000   0:01 -zsh
20825  2391  2391 20825 pts/7     2391 S+    1000   0:00  \_ sh test.sh
 2391  2392  2391 20825 pts/7     2391 S+    1000   0:00      \_ sh test.sh
 2392  2394  2391 20825 pts/7     2391 S+    1000   0:00      |   \_ sleep 5
 2391  2393  2391 20825 pts/7     2391 Sl+   1000   0:00      \_ zenity --progress --auto-close --auto-kill
点击取消

后立即

ps jf

 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 1179  2392  2391 20825 pts/7    20825 S     1000   0:00 sh test.sh
 2392  2394  2391 20825 pts/7    20825 S     1000   0:00  \_ sleep 5

显然,zenity会导致其PPID(在这种情况下为2391),但不知何故,23912392及其唯一的孩子{{1} } sleep)保持活力。为什么?不应该2394(显然what zenity does)也会杀死kill -1 2391的孩子吗?

1 个答案:

答案 0 :(得分:0)

我刚刚找到了一种对我有用的好方法,我认为使用bash在大多数情况下应该有效。

这个想法是,您在带有陷阱的容器中运行Zenity:zenity --auto-kill将SIGHUP发送给父进程时,父进程在死前将SIGHUP发送给同一进程组中的所有进程。所以关键是这样调用Zenity:

{
    trap 'pkill -g 0' HUP
    zenity --progress --auto-kill
}

在下面的代码中,我展示了如何将其与命名管道Feed Zenity一起使用,如果希望运行的过程在标准输出上生成数据,这将使事情变得更容易。

#! /bin/bash

...

zenityfifo=/tmp/zenityfifo$$
trap "rm --force $zenityfifo" EXIT

if [ -x /usr/bin/zenity -a "$DISPLAY" ]; then
    rm --force $zenityfifo
    mkfifo $zenityfifo
    ## The while loop is needed to keep the pipe blocking on read
    while read p < $zenityfifo; do echo $p; done | {
    trap 'pkill -g 0' HUP
    zenity --progress --title="resync" --auto-close --auto-kill
    } &
fi

while ...; do
    ...
    echo ... > $zenityfifo
done