ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

linux – 如果之后使用管道,为什么wait生成“不是这个shell的子代”错误?

2019-07-27 05:51:27  阅读:552  来源: 互联网

标签:bash linux shell pipe subprocess


在下面我创建一个后台进程并等待它完成.

$bash -c "sleep 5 | false"  &  wait $!
[1] 46950
[1]+  Exit 1                  bash -c "sleep 5 | false"
$echo $?
1

这有效,并在5秒后返回提示.

但是,如果我之后再使用一个管道,则wait会返回错误.

$bash -c "sleep 5 | false"  &  wait $!  | true
[1] 49493
-bash: wait: pid 49493 is not a child of this shell
hbaba@mbp-005063:~/misc$echo $?
0
hbaba@mbp-005063:~/misc$ps -T -f
  UID   PID  PPID   C STIME   TTY           TIME CMD
980771313 49493 69771   0 12:56AM ttys056    0:00.00 bash -c sleep 5 | false
980771313 49498 49493   0 12:56AM ttys056    0:00.00 sleep 5
    0 49555 69771   0 12:56AM ttys056    0:00.01 ps -T -f

这里发生了什么?

我使用的是bash版GNU bash,版本3.2.57(1)-release(x86_64-apple-darwin15)

我每次都可以重现等待错误.
我认为这与每个管道是一个单独的子shell有关. https://unix.stackexchange.com/a/127346/212862

也许等待$! command在错误的shell中查找子进程.
错误消息提到49493 pid.这确实是bash -c …命令的正确pid. ps -T表明了这一点.

有相关问题q1q2.但是在内置等待之后没有管道使用.

更新

我对&和bash之间的bash中的运算符优先级有误解.和|. @randomir在他的answer中指出了这一点.添加花括号使得等待先前的后台进程等待.例如:

{ bash -c "sleep 5 | false"  &  wait $! ; } | true

这不会返回相同的等待错误.

解决方法:

这里有两个要点:

> wait(内置shell)只能等待(shell的)子进程
>管道中的每个命令都在一个单独的子shell中运行

所以,当你说:

cmd & wait $!

然后cmd在你当前的shell中运行,在后台运行,而wait(作为shell的内置)可以等待cmd的PID,因为cmd是那个shell的子代(因此是等待的子代).

另一方面,当你说:

cmd & wait $! | cmd2

那么cmd仍然在你当前的shell中运行,但是管道会引入一个新的子shell用于等待(一个新的bash进程),其中cmd不是它的子进程,而wait不能等待它的兄弟(它的父进程的子进程).

作为shell语法的另一个澄清 – &运算符(以及;,&&和||)分隔管道,形成列表.因此,列表是一系列管道,而管道是由|分隔的一系列命令.

这意味着上面的最后一个例子相当于:

cmd & { wait $! | cmd2; }

而不是这个:

{ cmd & wait $! ; } | cmd2

这相当于你的预期.

标签:bash,linux,shell,pipe,subprocess
来源: https://codeday.me/bug/20190727/1550987.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有