说我当前的工作目录中有一个文件myfile
。如果命令正常执行,我想设置一个变量,但也要使用它的结果。
$ ls myfile && v=3
myfile
$ echo "$v"
3
但是现在我也想管道结果,所以我使用{ list; }
语法对命令进行分组:
$ unset v $ { ls myfile && v=3; } | grep myf myfile $ echo "$v" # v is not set
Bash reference manual -> 3.2.4.3 Grouping Commands说:
{ list; }
在花括号之间放置一个命令列表会导致列表成为 在当前shell上下文中执行。没有创建子shell。该 需要以下分号的分号(或换行符)。
所以,根据我的理解,v
应该设置为3.但它没有发生。为什么呢?
答案 0 :(得分:6)
这不是导致子壳创建的花括号,而是管道。
证明:
$ { ls && v=3; } > tmp
$ echo "$v"
3
引用Greg:
在大多数shell中,管道的每个命令都在一个单独的SubShell中执行。
答案 1 :(得分:4)
您可以使用BASH_SUBSHELL
变量来验证您是否在子shell中。
# BASH_SUBSHELL will print level of subshell from top due to pipe
{ unset v && ls file && v=3 && echo "$BASH_SUBSHELL - $v"; } | nl
1 file
2 1 - 3
# outside BASH_SUBSHELL will print 0
echo "$BASH_SUBSHELL - $v";
0 -
您可以使用管道命令打印1
,这意味着它位于子shell中,因此v
的值在外部不可用(从第二个输出显而易见)