zenity --auto-kill: Killing a subshell does not kill its child processes?

北城余情 提交于 2020-06-29 13:19:25

问题


I am having a really hard time understanding the behaviour of zenity --progress --auto-kill. It appears to not kill its parent process' subprocesses but to detach them somehow.

Consider the following shell script long-live-the-subshell.sh:

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

To reproduce the mentioned behaviour:

  • execute the script sh long-live-the-subshell.sh
  • click Cancel on the progress bar
  • wait another 5 seconds
  • see that woke up is output to the terminal

Example output:

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

The Hangup happens when you click Cancel. You then get your prompt back. However, after the sleep 5 finishes, woke up is output to the terminal.

ps jf immediately after running the script:

 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 immediately after clicking Cancel:

 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

Apparently, zenity kills its PPID (2391 in this case) but somehow both of the other children of 2391 (2392 and its only child sleep command 2394) stay alive. Why? Shouldn't a kill -1 2391 (which is obviously what zenity does) kill also the children of 2391?


回答1:


I have just found a nice way that works for me, and I think should work for most cases, using bash.

The idea is that you run Zenity in a container with a trap: when zenity --auto-kill sends a SIGHUP to the parent process, the parent process sends a SIGHUP to all processes in the same process group before dying. So the key is calling Zenity like this:

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

In the code below I show how I used this with a named pipe feeding Zenity, which makes things easier if you want the running process to produce data on standard output.

#! /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


来源:https://stackoverflow.com/questions/44607387/zenity-auto-kill-killing-a-subshell-does-not-kill-its-child-processes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!