Pipe Bash命令输出到stdout和变量 [英] Pipe Bash command output to stdout and to a variable

查看:388
本文介绍了Pipe Bash命令输出到stdout和变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须找到具有选定权限的文件,并列出它们及其编号.因此,我想将find命令的结果传递给shell和下一个命令,该输出我想存储在变量中,以便以后可以很好地显示.我想要类似的东西

I have to find files with selected permissions and list them as well as their number. Therefore I would like to pipe result of find command to shell and to the next command, which output I want to store in a variable so I could display it nicely later. I would like to have something like

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}部分不起作用.请帮忙.

but var=${wc -l} part doesn't work. Please help.

编辑 我知道我可以将命令的整个输出放到类似

EDIT I'm aware that I can put entire output of the command to a variable like

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

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

but then I need only the result of wc -l. How would I get this number from that variable? Would it be possible to display it in reversed order, number first and then the list?

推荐答案

复制到TTY(不是标准输出!)

Pipeline组件在子Shell中运行,因此即使它们确实分配了Shell变量(并且其语法是错误的),这些Shell变量也会在管道退出后立即取消设置(因为子Shell仅在管道运行时才存在) ).

Copying To A TTY (Not Stdout!)

Pipeline components run in subshells, so even if they do assign shell variables (and the syntax for that was wrong), those shell variables are unset as soon as the pipeline exits (since the subshells only live as long as the pipeline does).

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

Thus, you need to capture the output of the entire pipeline into your variable:

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

顺便说一句,顺便说一句,我会tee转到/dev/stderr/dev/fd/2,以避免使行为取决于TTY是否可用.

Personally, btw, I'd be teeing to /dev/stderr or /dev/fd/2 to avoid making behavior dependent on whether a TTY is available.

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

With bash 4.1, automatic file descriptor allocation lets you do the following:

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,分别):

With an older version of bash, you'd need to allocate a FD yourself -- in the below example, I'm choosing file descriptor number 3 (as 0, 1 and 2 are reserved for stdin, stdout and stderr, respectively):

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

这篇关于Pipe Bash命令输出到stdout和变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆