尝试实现以下目标:
command | { [[ ${PIPESTATUS[0] == 0 ]] && cmd_pipe_success || cmd_pipe_failed ; }
e.g。管道到不同的命令,具体取决于退出状态。
上述例子不起作用,例如:
command_ok() { sed 's/^/OK /'; }
command_no() { sed 's/^/NO /'; }
touch x
ls -l x 2>&1 | { [[ ${PIPESTATUS[0]} == 0 ]] && command_ok || command_no ; }
rm x
ls -l x 2>&1 | { [[ ${PIPESTATUS[0]} == 0 ]] && command_ok || command_no ; }
都打印OK
,因此在两种情况下都会运行command_ok
。
当command_no
的退出状态非零时,是否可以实现运行ls
?
我知道,有可能实现像
command_ok() { sed 's/^/OK /'; return 0; }
command_no() { sed 's/^/NO /'; return 0; }
touch x
res=$(ls -l x 2>&1)
[[ $? == 0 ]] && command_ok <<<"$res" || command_no <<<"$res"
rm x
res=$(ls -l x 2>&1)
[[ $? == 0 ]] && command_ok <<<"$res" || command_no <<<"$res"
但我希望避免辅助变量,也不想临时文件。有可能吗?
答案 0 :(得分:3)
如前所述,如果没有获得临时文件,就无法做到这一点:需要在原始命令运行完毕之前设置管道。但是,使用临时文件执行此操作非常简单:
TEMPFILE=$(mktemp)
if command > $TEMPFILE; then
command_ok < $TEMPFILE
else
command_no < $TEMPFILE
fi
rm $TEMPFILE
答案 1 :(得分:3)
这是不可能的,因为与管道连接的进程同时运行,而不是顺序运行。换句话说,只要获得第一个命令的退出状态,就会通过管道发送所有输出。管道始终连接两个正在运行的进程,并且正在运行的进程尚未具有退出状态。
答案 2 :(得分:2)
管道的组件并行运行(通常在单独的shell中),因此在运行第二个命令之前无法确定第一个命令是否成功。
答案 3 :(得分:0)
尝试使用TRAP命令。您可以根据命令的结果或脚本的返回值执行不同的操作。
例如,您可以说trap 'echo 'Exiting...'; exit' SIGQUIT
以下是一个充满示例的页面,其中包括一些可能有用的更多参与:http://www.ibm.com/developerworks/aix/library/au-usingtraps/