将Subshell后台进程pid分配给变量

扎诺纳

我目前正在子外壳程序中启动一个后台进程,并且想知道如何将其pid号分配给子外壳程序范围之外的变量?
我尝试了许多不同的方法,但MYPID始终保持不变0

MYPID = 0;
({ sleep 2 & }; $MYPID=$!)
({ sleep 2 & }; echo $!) > $MYPID

返回值的唯一方法是:

$MYPID=$({ sleep 2 & }; echo $!)

但是,这会丢弃后台处理指令,并且只会在2秒后返回结果。

斯蒂芬·查泽拉斯

bash 非交互式时,不应打印作业状态。

如果确实是用于交互式bash,则可以执行以下操作:

{ pid=$(sleep 20 >&3 3>&- & echo "$!"); } 3>&1

我们希望sleepstdout可以到达之前的位置,而不是到达$pid变量的管道因此,我们将外部标准输出保存在文件描述符3(3>&1)中,并sleep在命令替换内部将其还原因此pid=$(...),一旦echo终止就返回,因为没有任何东西给feed的管道保留打开文件描述符$pid

但是请注意,由于它是从子外壳程序启动的(此处是命令替换),因此sleep不会在单独的进程组中运行。因此,sleep 20 &与在终端上进行I / O操作不同。

也许更好的方法是使用一个支持生成无用的后台作业的外壳,例如zsh您可以执行的操作:

sleep 20 &! pid=$!

使用bash,您可以使用:

{ sleep 20 2>&3 3>&- & } 3>&2 2> /dev/null; pid=$!; disown "$pid"

bash输出[1] 21578到stderr。同样,在重定向到/ dev / null之前,我们先保存stderr,然后将其还原为sleep命令。这样一来,[1] 21578/dev/null,但sleep的标准错误去如常。

如果您仍然要将所有内容重定向到/ dev / null,则只需执行以下操作:

{ apt-get update & } > /dev/null 2>&1; pid=$!; disown "$pid"

要仅重定向标准输出:

{ apt-get-update 2>&3 3>&- & } 3>&2 > /dev/null 2>&1; pid=$!; disown "$pid"

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章