pipe bash命令输出到stdout和变量

时间:2017-03-06 22:18:50

标签: linux bash pipe stdout

我必须找到具有所选权限的文件,并列出它们的编号。因此,我想将find命令的结果传递给shell和下一个命令,我希望将哪个输出存储在一个变量中,以便以后可以很好地显示它。我想要像

这样的东西
for i in "$@"
do
    find $filename -perm $i | tee /dev/tty | var=${wc -l}
    echo "number of files with $i permission: $var"
done

var=${wc -l}部分不起作用。请帮忙。

修改 我知道我可以将命令的整个输出放到像

这样的变量中
var=$(find $filename -perm $i | tee /dev/tty | wc -l)

但是我只需要wc -l的结果。我如何从该变量中获取此数字?是否可以按相反的顺序显示它,先编号,然后列表?

1 个答案:

答案 0 :(得分:4)

复制到TTY(非标准输出!)

管道组件在子shell中运行,因此即使它们确实分配了shell变量(并且其语法错误),一旦管道退出,这些shell变量就会被取消(因为只有管道才会生效子shell) )。

因此,您需要将整个管道的输出捕获到您的变量中:

var=$(find "$filename" -perm "$i" | tee /dev/tty | wc -l)

就个人而言,顺便说一句,我tee /dev/stderr/dev/fd/2,以避免行为取决于TTY是否可用。

实际管道输入Stdout

使用bash 4.1,自动文件描述符分配允许您执行以下操作:

exec {stdout_copy}>&1 # make the FD named in "$stdout_copy" a copy of FD 1

# tee over to "/dev/fd/$stdout_copy"
var=$(find "$filename" -perm "$i" | tee /dev/fd/"$stdout_copy" | wc -l)

exec {stdout_copy}>&- # close that copy previously created
echo "Captured value of var: $var"

对于旧版本的bash,您需要自己分配FD - 在下面的示例中,我选择文件描述符编号3(因为0,1和2是为stdin保留的, stdout和stderr,分别):

exec 3>&1  # make copy of stdout

# tee to that copy with FD 1 going to wc in the pipe
var=$(find "$filename" -perm "$i" | tee /dev/fd/3 | wc -l)

exec 3>&-  # close copy of stdout