在shell脚本中获取命令stdout的fd文件名的便携方式

时间:2014-08-02 11:17:53

标签: shell unix pipe portability file-descriptor

我很确定我在这方面缺少术语,这可能是谷歌让我失败的原因。是否有一种便携且简单的方法可将标准输出重定向到多个命令。

换句话说,我如何解决这个可移植性问题:

$ /bin/bash -c '(echo to your mom) | tee >(read b; echo "agent 1 reports $b") >(read b; echo "agent 2 reports $b")  >(read b; echo "agent 3 reports $b")'
to your mom
agent 1 reports to your mom
agent 2 reports to your mom
agent 3 reports to your mom
$ /bin/zsh -c '(echo to your mom) | tee >(read b; echo "agent 1 reports $b") >(read b; echo "agent 2 reports $b")  >(read b; echo "agent 3 reports $b")'
to your mom
agent 1 reports to your mom
agent 3 reports to your mom
agent 2 reports to your mom
$ /bin/sh -c '(echo to your mom) | tee >(read b; echo "agent 1 reports $b") >(read b; echo "agent 2 reports $b")  >(read b; echo "agent 3 reports $b")'
/bin/sh: 1: Syntax error: "(" unexpected

请注意,输出顺序不是问题,/bin/sh会产生错误。

1 个答案:

答案 0 :(得分:2)

使用命名管道:

#!/bin/sh

fifo1=$(exec mktemp --dry-run)
mkfifo "$fifo1"
( read b; echo "agent 1 reports $b" ) < "$fifo1" &

fifo2=$(exec mktemp --dry-run)
mkfifo "$fifo2"
( read b; echo "agent 2 reports $b" ) < "$fifo2" &

fifo3=$(exec mktemp --dry-run)
mkfifo "$fifo3"
( read b; echo "agent 3 reports $b" ) < "$fifo3" &

echo to your mom | tee "$fifo1" "$fifo2" "$fifo3"

rm -f "$fifo1" "$fifo2" "$fifo3"

用法:

sh script.sh

输出:

to your mom
agent 2 reports to your mom
agent 1 reports to your mom
agent 3 reports to your mom

这就是科学。通过功能,您可以根据自己的喜好制作技术,使您轻松管道。