给定一个类似“A | B | C | D | E”的管道,我想让步骤C以步骤B的结果为条件。这样的事情:
A | B | if [ $? -ne 0 ]; then C; else cat; fi | D | E
但这似乎不起作用;无论B的结果如何,C都不会执行。我正在寻找更好的解决方案。
我知道管道的每一步都在自己的子shell中运行。所以我无法将环境变量传递回管道。但是这个管道在Gnu Parallel环境中,许多这样的管道同时运行,并且它们都不知道任何唯一值(它们只处理数据流而不需要知道源,父脚本处理必要的分离)。这意味着使用临时文件也不实用,因为没有任何方法可以使文件名唯一。甚至$$似乎也没有给我一个在每个步骤中都相同的值。
答案 0 :(得分:4)
您无法使管道成为条件,因为命令是并行运行的。如果在C
退出之前未运行B
,那么B
的输出将通过管道输送到哪里?
您需要将B
的输出存储在变量或临时文件中。例如:
out=$(mktemp)
trap 'rm "$out"' EXIT
if A | B > "$out"; then
C < "$out"
else
cat "$out"
fi | D | E
答案 1 :(得分:1)
在陈述问题的方式上存在逻辑上的不可能性。
假设像A | B
这样的管道。管道的存在是因为我们希望B在A完成之前从A开始读取。因此,当B开始时(这将是你的状况被评估的时候),A还不知道它是否会失败或成功,所以B也不知道。
你可以做的是,有一个回声,作为它的最后一行,某种类型的状态代码。然后B可以从标准输入读取,保存输入(作为临时文件,变量到变量),然后一旦收到最后一行,检查状态然后采取行动。
当然,另一种方法是让A存储自己的输出,然后在完成时,在条件内部使用A(并从管道中消除B)。