如何在打印输出的同时将命令输出存储在变量中?

fed*_*qui 10 bash gnu stdout

说我想要echo一些东西并在变量中捕获它,同时我在屏幕上看到它.

echo "hello" | tee tmp_file
var=$(< tmp_file)
Run Code Online (Sandbox Code Playgroud)

所以现在我可以hello在终端中看到并将其保存到变量中$var.

但是,有没有办法在不使用临时文件的情况下执行此操作?tee似乎不是解决方案,因为它说(从man tee)读取标准输入并写入标准输出和文件,而这里它是标准输出的两倍.

如果这很重要,我在Bash 4.3中.

123*_*123 20

使用tee将其直接指向屏幕而不是stdout

$ var=$(echo hi | tee /dev/tty)
hi
$ echo $var
hi
Run Code Online (Sandbox Code Playgroud)

  • 这是有效的,而且正是提问者所要求的.请注意,如果脚本的调用者正在使用stdout,他们将看不到你发送给/ dev/tty的内容(这应该是显而易见的,但它让我绊倒了,所以我想我会分享). (4认同)
  • @vladkras 不,它没有,如果你想保留空格/特殊字符,请引用变量 (2认同)

Leo*_*Leo 8

管道成功tee.

这是我在这个问题中解决的方法.

var=$(echo "hello" | tee /dev/tty)
Run Code Online (Sandbox Code Playgroud)

然后你可以$var用来取回存储的变量.

例如:

var=$(echo "hello" | tee /dev/tty); echo "$var world"
Run Code Online (Sandbox Code Playgroud)

将输出:

hello
hello world
Run Code Online (Sandbox Code Playgroud)

您可以使用管道做更多事情,例如我想在终端中打印一个短语,同时告诉它中有多少"l":

count=$(echo "hello world" | tee /dev/tty | grep -o "l" | wc -l); echo "$count"
Run Code Online (Sandbox Code Playgroud)

这将打印:

hello world
3
Run Code Online (Sandbox Code Playgroud)


Ign*_*ams 5

将其发送到stderr。

var="$(echo "hello" | tee /dev/stderr)"
Run Code Online (Sandbox Code Playgroud)

或将标准输出复制到更高的FD并将其发送到那里。

$ exec 10>&1
$ var="$(echo "hello" | tee /proc/self/fd/10)"
hello
$ echo "$var"
hello
Run Code Online (Sandbox Code Playgroud)

  • @fedorqui:`exec`在bash中有两个作用。首先是用新流程替换当前流程。第二种是使用重定向语法对文件描述符进行操作。如果未指定命令,则将FD重定向应用于当前进程。 (2认同)

Mat*_*ice 5

伊格纳西奥回答的变体:

$ exec 9>&1                                                                                                              
$ var=$(echo "hello" | tee >(cat - >&9))   
hello                                                                              
$ echo $var
hello
Run Code Online (Sandbox Code Playgroud)

详情请见:https : //stackoverflow.com/a/12451419/1054322