我有以下形式的命令
input | tee >(subshell) | mainshell
子 shell 和主 shell 都写入标准输出。所以他们的输出不同步。例如
echo "Hello\nWorld" | tee >(grep -o ell | tr 'a-z' 'A-Z') | grep orld | sed 's/orl/ORL/g'
上面的命令打印
ELL
WORLd
有时和
WORLd
ELL
其他时间。
有没有一种简单的方法可以确保它们按预期顺序排列,而不必使用临时文件/命名的 fifo?可能打开一些文件描述符重定向会有帮助?
更新:
按顺序,我指的是主 shell 的输出,然后是子 shell 的输出(反之亦然)。如果它是确定性的,我可以将它们交换到我的需要。
同样可以通过命名 fifo 来实现,如下所示
mkfifo f1 f2
echo "Hello\nWorld" | tee >(grep -o ell | tr 'a-z' 'A-Z' > f1) | grep orld | sed 's/orl/ORL/g' > f2 &
cat f1 f2
rm f1 f2
我想知道是否可以避免临时 fifo 或文件。
答案1
答案2
GNU Parallel--tee
可以--keep-order
强制顺序保持不变:
ell() {
grep -o ell | tr 'a-z' 'A-Z'
}
orld() {
grep orld | sed 's/orl/ORL/g'
}
export -f ell
export -f orld
echo "Hello\nWorld" | parallel -k --tee --pipe ::: ell orld
然而,它确实在幕后使用 fifo 和临时文件。但如果您的目标只是不想自己处理这个问题,那么这可能是一个解决方案。
该解决方案使用 tmpfiles,但它们几乎立即取消链接:
myfunc1() { grep -o ell | tr 'a-z' 'A-Z'; }
myfunc2() { grep orld | sed 's/orl/ORL/g'; }
touch tmp1 tmp2
(
echo "Hello\nWorld" |
tee >( (rm tmp1; myfunc1) > tmp1 ) |
(rm tmp2; myfunc2) > tmp2
cat <&3
cat <&4
) 3< tmp1 4< tmp2
或者更短:
(
rm tmp1 tmp2
echo "Hello\nWorld" |
tee >( grep -o ell | tr 'a-z' 'A-Z' >&5 ) |
grep orld | sed 's/orl/ORL/g' >&6
cat <&3
cat <&4
) 5> tmp1 6> tmp2 3< tmp1 4< tmp2