考虑以下命令块:
if [[ ${EXTRA_PROCESS} -eq 1 ]]; then
producer | tee >(calc1 > ${out1}) >(calc2 > ${out2}) | consumer
else
producer | tee >(calc1 > ${out1}) | consumer
fi
这可以做它应该做的事情。但是,这相当于很多代码重新分区。所以我改变它看起来像这样:
TEE="tee >(calc1 > ${out1})"
if [[ ${EXTRA_PROCESS} -eq 1 ]]; then
TEE="$TEE >(calc2 > ${out2})"
fi
producer | ${TEE} | consumer
这远远少于代码重复。不幸的是,脚本现在完全坏了。当我运行它时,它会在当前目录中创建三个巨型文件:
blackbox:~ # ls
>
>(calc1
>(calc2
...
(我印象深刻的是,甚至可能首先拥有带有这些名字的文件......删除它们会更有趣!)
有人可以解释
答案 0 :(得分:1)
为什么Bash在字面上处理字符串而不是解释 它们?
当您将重定向运算符存储在字符串中时,这些运算符往往会失去其特殊含义。这就是您能够拥有>(calc1
等文件名的原因。
我如何强迫Bash实际按照我的要求行事?
我建议坚持你在第一个代码块中完成它的方式。它似乎可能会重复代码,但不建议使用替代方法(见下文)。
替代(not recommended
):
eval "producer | ${TEE} | consumer"
更好的选择是使用函数:
foo1() {
producer | tee >(calc1 > ${out1}) >(calc2 > ${out2}) | consumer;
}
foo2() {
producer | tee >(calc1 > ${out1}) | consumer;
}
if [[ ${EXTRA_PROCESS} -eq 1 ]]; then
foo1
else
foo2
fi
答案 1 :(得分:0)
我找到了解决方案:
if [[ ${EXTRA_PROCESS} -eq 1 ]]; then
function Tee()
{
tee >(calc1 > ${out1}) >(calc2 > ${out2})
}
else
function Tee()
{
tee >(calc1 > ${out1})
}
fi
producer | Tee | consumer
对于实际显示的示例,这是更多的打字。 然而,当您有多个独立的开/关选项时,这样做可以防止稍微不同的管道组合爆炸。
producer | Option1 | Option2 | Option3 | consumer