【问题标题】:zenity --auto-kill: Killing a subshell does not kill its child processes?zenity --auto-kill:杀死一个子shell不会杀死它的子进程?
【发布时间】:2017-06-17 17:22:11
【问题描述】:

我很难理解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),但不知何故,2391 的其他孩子(2392 及其唯一的孩子sleep 命令2394)都活着。为什么? kill -1 2391(显然是what zenity does)不应该也杀死2391 的孩子吗?

【问题讨论】:

  • 如果你将子shell改为复合语句会发生什么,即{ echo...; sleep ...; echo ...; } | zenity...
  • @MarkSetchell 如果我将圆括号更改为花括号,则行为是相同的。 woke up 仍然输出到终端。
  • 真的没有人知道这件事吗? :-O
  • 这可能会有所帮助...bernaerts.dyndns.org/linux/…

标签: shell kill subshell zenity


【解决方案1】:

我刚刚找到了一种适合我的好方法,我认为应该适用于大多数情况,使用 bash。

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

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

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

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

【讨论】:

    猜你喜欢
    • 2010-12-02
    • 2016-01-24
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    相关资源
    最近更新 更多