如何将子 shell PID 存储在变量中,以便以后可以终止子 shell 及其后台进程?

How can I store a subshell PID in a variable so that I can kill the subshell and its background process later?

提问人:Gigi Bayte 2 提问时间:2/27/2023 最后编辑:Gigi Bayte 2 更新时间:2/27/2023 访问量:55

问:

因此,假设我正在运行一个带有后台进程的子 shell,如下所示:

(command &)

我希望能够将这个子进程的 PID 存储到 bash 变量中,以便我以后可以杀死子 shell 及其正在运行的后台进程。我该怎么做?

注意:这很可能是重复的,但我正在努力实现许多其他答案。因此,即使这个问题被标记为重复,如果有人仍然可以提供答案,我将不胜感激。

我尝试过的一些事情:

pid="$((echo "$BASHPID" && command &))"
pid2="$((command & echo "$BASHPID"))"
pid3=(echo "$BASHPID" && command &)
pid4=(command & echo "$BASHPID")
bash 进程 pid 子shell

评论

0赞 markp-fuso 2/27/2023
你使用而不是有什么原因吗?我并不是说你的方法是对的还是错的,只是好奇你选择这种方法的原因是什么?(command &)command &
1赞 Gigi Bayte 2 2/27/2023
@markp扶桑,我按照建议添加了一些尝试。我首先使用子 shell 的原因是为了抑制与后台进程相关的输出(例如 和[1] <pid>[1]+ Terminated: 15 <command>)
0赞 KamilCuk 2/27/2023
in the first place is to suppress background-process related output?脚本中没有后台输出。也许只是 ?set +m
2赞 Gigi Bayte 2 2/27/2023
@KamilCuk我有点不明白你的意思。在这种情况下,如果我不使用子 shell,就会发生上述后台进程输出。澄清一下,这是针对我放入 ..bashrc
0赞 chepner 2/27/2023
您将命令替换 () 与算术表达式 () 混淆。$(...)$((...))

答:

1赞 KamilCuk 2/27/2023 #1

有很多方法可以 https://en.wikipedia.org/wiki/Inter-process_communication。例如,使用 fifo:

pidfile=$(mktemp -n)
mkfifo "$pidfile"
(command & echo $! > "$pidfile")
read pid < "$pidfile"
rm "$pidfile"
2赞 markp-fuso 2/27/2023 #2

一个想法:

$ read -r x < <(sleep 240 & echo $!)       # alternative: replace $! with $BASHPID
                ^^^^^^^^^        ^^    
$ echo "$x"
1887
^^^^
$ ps -aef|egrep sleep
myuser    1887       1 pty1     16:00:17 /usr/bin/sleep
          ^^^^                                    ^^^^^
$ pgrep -a sleep
1887 sleep 240
^^^^ ^^^^^^^^^

评论

2赞 KamilCuk 2/27/2023
但这会隐藏输出。您可以这样做,以便后台命令仍然可以写入 stdout。exec 3>&1; read pid < <(sleep 240 >&3 & echo $!)
0赞 Diego Torres Milano 2/27/2023 #3

也许实现它的最短方法是使用:coproc

#! /bin/bash

coproc ./mycommand
pid=$COPROC_PID