bash:从管道中分配变量?

agc*_*agc 2 bash

bash,使用管道输入分配变量的最有效方法是什么 - 仅使用从左到右的语法?假设管道的左侧是seq 3,所以我们想要:

seq 3 | x=<put some code here>
Run Code Online (Sandbox Code Playgroud)

注意:虽然功能上可能相同,但不是答案:

x=`seq 3`
Run Code Online (Sandbox Code Playgroud)

...因为seq 3不在管道的左侧.

对于这个Q,请忽略超出变量内存的可能性,管道当然可以做到.

Cha*_*ffy 9

BashFAQ#24详细介绍了这一点.

只有在引用它的代码位于该管道的右侧时,您才能可靠地使用在管道右侧收集的变量.

#!/bin/bash
echo "hello" | { read -r var; echo "Read value: $var"; }
echo "After the pipeline exited, var contains: $var"
Run Code Online (Sandbox Code Playgroud)

典型输出是:

Read value: hello
After the pipeline exited, var contains:
Run Code Online (Sandbox Code Playgroud)

POSIX sh规范既不要求也不排除在同一shell中执行的管道的右侧,后者执行后续命令.因此,外壳可以执行read在地方执行相同的外壳第二行echo第三-但bash中,具体地讲,不会,除非这样做lastpipe外壳选项启用.


mkl*_*nt0 7

为了补充查尔斯·达菲的有用的答案,重点是使其工作bash:

默认情况下,在Bash v4.1-上,(多段)管道中的任何变量创建/修改总是发生在子shell中,因此调用shell将无法看到结果.

Bash v4.2 +中,您可以设置选项lastpipe以使最后一个管道段在当前 shell中运行,以便在那里可以看到变量创建/修改.

为了在交互式 shell中工作,您必须另外关闭作业控制set +m.

这是一个完整的例子(Bash v4.2 +):

$ unset x; shopt -s lastpipe; set +m; seq 3 | x=$(cat); echo "$x"
1
2
3
Run Code Online (Sandbox Code Playgroud)

那说,

x=$(seq 3)
Run Code Online (Sandbox Code Playgroud)

(相当于你的现代版本x=`seq 3`)要简单得多 - 它符合POSIX标准,因此也适用于较旧的Bash版本,它不需要摆弄全局选项.