2013-06-24 96 views
8

这只是一个假设性问题 - 没有解决任何实际问题 - 只能学习bash。粘贴tee命令的结果

随着tee命令是可能的分割输出到多个不同的数据流,如:

command1 | tee >(commandA1 | commandA2 >file1) >(commandB1 | commandB2 >file2) >file0 

所以图形完成下一

    ---commandA1---commandA2--> file1 
       /
command1---tee-------> file0 
       \ 
        ---commandB1---commandB2--> file2 

现在,随着paste命令可以例如

paste file1 file2 | command3 

而我又可以从不同的程序重定向到粘贴输出,如:

paste <(ls) <(ls) | command3 

的问题是:有可能在两股稍微加入到一个,像

    ---commandA1---commandA2--- 
       /       \ 
command1---tee-------> file0     --- paste---command3 
       \       /
        ---commandB1---commandB2--- 

Ps:表示没有中间文件...

+5

不是没有中间文件或命名管道。请参阅'mkfifo' – SheetJS

+3

这是一个我喜欢看到的问题 - 有些什么不是微不足道的。不幸的是,我不知道bash足够深入地展示如何通过@Nirk建议的“命名管道”实现此目标... +1 – kobame

回答

3

下面介绍如何使用命名为p IPES:

trap "rm -f /tmp/file1 /tmp/file2; exit 1" 0 1 2 3 13 15 
mkfifo /tmp/file1 
mkfifo /tmp/file2 
command1 | tee >(commandA1 | commandA2 >/tmp/file1) >(commandB1 | commandB2 >/tmp/file2) >file0 
paste /tmp/file1 /tmp/file2 | command3 
rm -f /tmp/file1 /tmp/file2 
trap 0 

工作实施例:

$ cd -- "$(mktemp -d)" 
$ trap "rm -f pipe1 pipe2; exit 1" 0 1 2 3 13 15 
$ mkfifo pipe1 pipe2 
$ printf '%s\n' 'line 1' 'line 2' 'line 3' 'line 4' | tee \ 
>(sed 's/line /l/' | head -n 2 > pipe1) \ 
>(sed 's/line /Line #/' | tail -n 2 > pipe2) \ 
> original.txt 
$ paste pipe1 pipe2 | sed 's/\t/ --- /' 
l1 --- Line #3 
l2 --- Line #4 
$ rm pipe1 pipe2 
$ trap 0 
+0

我没有写它,@JonathanLeffler补充说(在添加工作示例之前) 。 – Barmar

+0

@ l0b0:陷阱中的“退出1”表示过程失败; '退出0'会给人以错误的印象,认为这个过程是成功的。如果不添加'exit'就意味着'以最后一个命令的状态退出,这将是'rm -f',这将成功,所以退出状态将为0.'陷阱'可以确保临时FIFO在外壳能够移除它们时被移除。如果你用'kill -9'杀死这个进程,那么它就没有办法清理。但是如果使用HUP,INT,QUIT,PIPE或TERM(1,2,3,13,15),那么在退出之前,外壳将自行清理。 –

+0

@JonathanLeffler令人困惑的是,您在陷阱信号列表中加入了'0',这意味着它会在正常退出期间运行并将其变为失败退出。但实际上不会发生这种情况,因为您在最后以'trap 0'退出时禁用了陷阱,所以原始陷阱命令中没有这一点。 – Barmar