如何从管道内部获取管道命令的退出状态?
考虑我有以下命令行: do-things arg1 arg2 | Progress-meter "Doing things...";,其中 progress-meter
是我想要实现的 bash 函数。它应该在运行 do-things arg1 arg2
之前或并行打印 Doing things...
(因此,无论如何它都会在一开始就被打印),并记录 stdout+ do-things
命令的 stderr,并检查其退出状态。如果退出状态为 0,则应打印 [ OK ]
,否则应打印 [FAIL]
并转储记录的输出。
目前,我使用progress-meter "Doing things..." "do-things arg1 arg2"; 完成了一些事情,并且在内部使用了eval
uating第二个参数,这是笨拙且我不喜欢这样,并相信有更好的解决方案。
管道语法的问题是我不知道如何从管道内部获取do-things
'退出状态? $PIPESTATUS
似乎只有在管道中的所有命令完成后才有用。
也许像 progress-meter "Doing things..." <(do-things arg1 arg2);
这样的进程替换会很好,但在这种情况下我也不知道如何退出do-things
的状态。
我很高兴听到是否有其他一些简洁的语法可以实现相同的任务,而无需像我的示例中那样转义要执行的命令。
我非常希望得到社区的帮助。
UPD1:由于问题似乎不够清楚,我解释一下:
我想要可以使用命令提供的 bash 函数,该函数将与函数并行执行,并且 bash函数将接收它的 stdout+stderr,等待完成并获取其退出状态。
使用eval
的示例实现:
progress_meter() {
local output;
local errcode;
echo -n -e $1;
output=$( {
eval "${cmd}";
} 2>&1; );
errcode=$?;
if (( errcode )); then {
echo '[FAIL]';
echo "Output was: ${output}"
} else {
echo '[ OK ]';
}; fi;
}
因此这可以用作progress_meter“Do things...”“do-things arg1 arg2”
。我想要同样的东西而不需要评估。
Consider I have following commandline: do-things arg1 arg2 | progress-meter "Doing things...";
, where progress-meter
is bash function I want to implement. It should print Doing things...
before running do-things arg1 arg2
or in parallel (so, it will be printed anyway at the very beginning), and record stdout+stderr of do-things
command, and check it's exit status. If exit status is 0, it should print [ OK ]
, otherwise it should print [FAIL]
and dump recorded output.
Currently I have things done using progress-meter "Doing things..." "do-things arg1 arg2";
, and eval
uating second argument inside, which is clumsy and I don't like that and believe there is better solution.
The problem with pipe syntax is that I don't know how can I get do-things
' exit status from inside the pipeline? $PIPESTATUS
seems to be useful only after all commands in pipeline finished.
Maybe process substitution like progress-meter "Doing things..." <(do-things arg1 arg2);
will be fine, but in this case I also don't know how can I get exit status of do-things
.
I'll be happy to hear if there is some other neat syntax possible to achieve same task without escaping command to be executed like in my example.
I greatly hope for the help of community.
UPD1: As question seems not to be clear enough, I paraphrase it:
I want bash function that can be fed with command, that will execute in parallel to function, and bash function will receive it's stdout+stderr, wait for completion and get its exit status.
Example implementation using eval
s:
progress_meter() {
local output;
local errcode;
echo -n -e $1;
output=$( {
eval "${cmd}";
} 2>&1; );
errcode=$?;
if (( errcode )); then {
echo '[FAIL]';
echo "Output was: ${output}"
} else {
echo '[ OK ]';
}; fi;
}
So this can be used as progress_meter "Do things..." "do-things arg1 arg2"
. I want the same without eval.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为什么要
评估
东西?假设您有一个固定的progress-meter
参数,您可以执行以下操作:并调用它
如果您坚持将
progress-meter
放入管道中,恐怕你最好的选择是这样的Why
eval
things? Assuming you have one fixed argument toprogress-meter
, you can do something like:and call it
If you insist on putting
progress-meter
in a pipeline, I'm afraid your best bet is something like我不确定我是否理解您到底想要实现什么目标,
但您可以检查 pipefail 选项:
例如:
编辑:我刚刚阅读了您对另一篇文章的评论。你为什么不直接处理这个错误呢?
I'm not sure I understand what exactly you're trying to achieve,
but you could check the pipefail option:
For example:
Edit: I just read your comment on the other post. Why don't you just handle the error?
让管道中的脚本通过代理进行通信(很像黑板模式:一个人在黑板上写,另一个人读):
修改您的
do-things
脚本,以便它报告其内容修改您的
progress-meter
脚本以读取该文件,如果您愿意,可以使用命令行开关,以免硬编码黑板文件的名称,以报告它所运行的程序的退出状态正在报告进度。Have your scrips in the pipeline communicate by proxy (much like the Blackboard Pattern: some guy writes on the blackboard, another guy reads it):
Modify your
do-things
script so that it reports its exit status to a file somewhere.Modify your
progress-meter
script to read that file, using command line switches if you like so as not to hardcode the name of the blackboard file, for reporting the exit status of the program that it is reporting the progress for.