【问题标题】:Kill process on the left side of a pipe杀死管道左侧的进程
【发布时间】:2023-04-04 18:56:01
【问题描述】:

我在 bash 中有以下内容:

富 |酒吧

我希望foo 在脚本终止时死掉(使用 TERM 信号)。不幸的是,他们都没有死。我试过这个:

exec foo | bar

这完全没有取得任何成果。然后我尝试了这个:

function run() {
    "$@" &
    pid=$!
    trap "kill $pid" EXIT
    wait
}

run foo | bar

再一次,什么都没有。现在我多了一个进程,当我终止父进程时,它们都没有死。

【问题讨论】:

  • 在单独的进程组中运行 foo|bar 可能会有所帮助。 related
  • 您能给我们举个例子吗? bash -c 'sleep 50 | sleep 50' & kill $! 将正确终止两个睡眠...
  • @Camusensei 不,它没有。试试这个:bash -c 'sleep 50 | sleep 50' & sleep 1; kill $!
  • 确实如此。我将答案更改为有效的答案,请查看。

标签: bash process pipe


【解决方案1】:

我会使用命名管道,这样可以更轻松地获取 foo 的进程 ID。

trap 'kill $foo_pid; rm -f foo_out' EXIT

mkfifo foo_out
foo > foo_out & foo_pid=$!
bar < foo_out

【讨论】:

    【解决方案2】:

    通过杀死整个进程组而不仅仅是bash(父进程),您也可以向所有子进程发送终止信号。 语法示例如下:

    kill -SIGTERM -$!
    kill -- -$!
    

    例子:

    bash -c 'sleep 50 | sleep 40' & sleep 1; kill -SIGTERM -$!; wait; ps -ef | grep -c sleep
    [1] 14683
    [1]+  Terminated              bash -c 'sleep 50 | sleep 40'
    1
    

    请注意,wait 在这里等待 bash 被有效杀死,这需要几毫秒。 另请注意,最终结果 (1) 是“grep sleep”本身。结果 3 表明这不起作用,因为两个额外的睡眠进程仍在运行。

    kill 手册提到:

    -n
    where n is larger than 1. All processes in process group n are signaled.
    When an argument of the form '-n' is given, and it is meant to denote a
    process group, either the signal must be specified first, or the argument
    must be preceded by a '--' option, otherwise it will be taken as the signal
    to send.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      相关资源
      最近更新 更多