【发布时间】:2011-10-07 09:42:03
【问题描述】:
考虑我有以下命令行:do-things arg1 arg2 | progress-meter "Doing things...";,其中progress-meter 是我想要实现的 bash 函数。它应该在运行do-things arg1 arg2或并行运行之前打印Doing things...(因此,无论如何它都会在一开始打印),并记录do-things命令的stdout+stderr,并检查它的退出状态。如果退出状态为 0,则应打印 [ OK ],否则应打印 [FAIL] 并转储记录的输出。
目前我使用 progress-meter "Doing things..." "do-things arg1 arg2"; 和 evaluating 内部的第二个参数完成了一些事情,这很笨拙,我不喜欢这样,并且相信有更好的解决方案。
管道语法的问题是我不知道如何从管道内部获取do-things'退出状态? $PIPESTATUS 似乎只有在管道中的所有命令完成后才有用。
也许像progress-meter "Doing things..." <(do-things arg1 arg2); 这样的进程替换会很好,但在这种情况下,我也不知道如何获得do-things 的退出状态。
我很高兴听到是否有其他简洁的语法可以实现相同的任务,而无需像我的示例中那样转义要执行的命令。
我非常希望得到社区的帮助。
UPD1:由于问题似乎不够清楚,我解释一下:
我想要可以输入命令的bash函数,它将与函数并行执行,bash函数将接收它的stdout+stderr,等待完成并获取其退出状态。
使用evals 的示例实现:
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"。我想要没有 eval 也一样。
【问题讨论】:
-
感谢 Emil 的修复,但使用“evil”而不是“eval”是故意的。
标签: bash shell process try-catch