zenity --auto-kill:杀死subshell不会杀死其子进程吗? [英] zenity --auto-kill: Killing a subshell does not kill its child processes?
问题描述
我很难理解zenity --progress --auto-kill
的行为.它似乎不是杀死其父进程的子进程,而是以某种方式分离它们.
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.
考虑以下shell脚本long-live-the-subshell.sh
:
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
要重现上述行为:
- 执行脚本
sh long-live-the-subshell.sh
- 点击进度栏上的取消
- 再等5秒钟
- 看到
woke up
输出到终端
- 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
示例输出:
> sh long-live-the-subshell.sh
sleeping...
Hangup
> woke up
Hangup
会在您单击取消时发生.然后,您会得到提示.但是,sleep 5
完成后,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
:
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
),但是以某种方式2391
的其他两个子项(2392
和其唯一的子sleep
命令2394
)仍然有效.为什么? kill -1 2391
不应该(显然是 zenity会做什么) )还会杀死2391
的孩子吗?
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
?
推荐答案
我刚刚找到了一种对我有用的好方法,并且我认为使用bash在大多数情况下应该适用.
I have just found a nice way that works for me, and I think should work for most cases, using bash.
这个想法是您在带有陷阱的容器中运行Zenity:zenity --auto-kill
将SIGHUP发送到父进程时,父进程在死前将SIGHUP发送到同一进程组中的所有进程.所以关键是这样称呼Zenity:
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
}
在下面的代码中,我展示了如何将它与命名管道Feed Zenity一起使用,如果希望运行的过程在标准输出上生成数据,这将使事情变得更容易.
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
这篇关于zenity --auto-kill:杀死subshell不会杀死其子进程吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!