繁体   English   中英

处理替代和退出代码

[英]Process Substitution and Exit Codes

我想在给定的时间内监视过程的输出。 除了给我执行的命令的返回值外,以下所有我想做的事情。

cmd='cat <<EOF
My
Three
Lines
EOF
exit 2
'

perl -pe "if (/Hello/) { print \$_; exit 1 }" <(echo "$cmd" | timeout 
5 bash)

有谁有办法获得那个返回值? 我在这里查看了其他问题,但是没有一种答案适用于这种情况。

仅限Bash 4.4:使用$! 收集PID,然后wait该PID

Bash仅使收集版本4.4中的进程替换的退出状态成为可能。 由于无论如何我们都需要该版本,最好也使用自动FD分配。 :)

exec {psfd}< <(echo "hello"; exit 3); procsub_pid=$!
cat <&$psfd           # read from the process substitution so it can exit
exec {psfd}<&-        # close the FD
wait "$procsub_pid"   # wait for the process to collect its exit status
echo "$?"

...正确返回:

3

在您的代码的上下文中,可能看起来像:

cmd() { printf '%s\n' My Three Lines; exit 2; }
export -f cmd

exec {psfd}< <(timeout 5 bash -c cmd); ps_pid=$!
perl -pe "if (/Hello/) { print \$_; exit 1 }" <&$psfd
echo "Perl exited with status $?"
wait "$ps_pid"; echo "Process substitution exited with status $?"

...作为输出发出:

Perl exited with status 0
Process substitution exited with status 2

简单答案:做其他事情

尽管可以在最近的Shell版本中解决此问题,但通常来说,进程替换会占用退出状态。 更重要的是,在给出的示例中根本不需要它们。

如果设置pipefail shell选项,则管道中的任何组件(不仅是最后一个组件)的退出状态都会反映在管道的退出状态中; 因此,您不需要使用进程替换也可以尊重perl的退出状态。

#!/usr/bin/env bash

set -o pipefail

cmd() { printf '%s\n' My Three Lines; exit 2; }
export -f cmd

timeout 5 bash -c 'cmd' | perl -pe "if (/Hello/) { print \$_; exit 1 }"
printf '%s\n' \
  "Perl exited with status ${PIPESTATUS[1]}" \
  "Process substitution exited with status ${PIPESTATUS[0]}"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM