我很难理解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
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
),但不知何故,2391
(2392
及其唯一的孩子{{1} } sleep
)保持活力。为什么?不应该2394
(显然what zenity does)也会杀死kill -1 2391
的孩子吗?
答案 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