我想将一个命令的输出和返回码通过管道传递给另一个命令:
somecommand | anothercommand.sh
anothercommand.sh 可以读取 somecommand 的输出,但是该脚本如何读取 的返回码somecommand
?
$PIPESTATUS
没有有关 anotherstatus.sh 中先前命令的信息(这是预期的)。
答案1
{ somecommand; echo "STATUS:${?}"; } | anothercommand.sh
将发送状态作为管道中数据的最后一行。因此,只有读取完所有前面的数据后才能使用它。仅当状态不好时才可以发送状态,因此它将充当“取消”运算符。
如果管道中数据的顺序不重要,您可以将tac
数据放在第一位,这样状态就排在第一位;或者将其全部缓冲在内存中(可能在 awk 数组中),或者按照 Stephen 建议使用文件,具体取决于容量。
如果somecommand
仅在成功后才生成数据,那么无论如何都会首先出现错误的状态行(自行)。事实上,“成功”通常可以通过“我是否获得了预期的数据”来衡量。
您还可以将 stderr 重定向为2>&1
并在管道数据中查找错误消息(如果它们很容易与有效数据区分开来)。
答案2
您无法使用管道执行此操作,因为管道中的命令可能会并行运行 - 当anothercommand.sh
启动时,somecommand
尚未完成,并且其退出代码未知。
如果您需要此信息,则必须拆分管道并序列化执行:
somecommand > tmpfile
anothercommand.sh $? < tmpfile
(通过适当的构造tmpfile
,例如使用mktemp
。)