Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 大括号和管道中的分组命令不会保留变量_Bash - Fatal编程技术网

Bash 大括号和管道中的分组命令不会保留变量

Bash 大括号和管道中的分组命令不会保留变量,bash,Bash,假设我在当前工作目录中有一个文件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 将命令列表放置在大括号之间会导

假设我在当前工作目录中有一个文件
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 将命令列表放置在大括号之间会导致该列表 在当前shell上下文中执行。没有创建子shell。这个 以下列表需要分号(或换行符)


因此,根据我的理解,
v
应该设置为3。但事实并非如此。为什么?

创建子shell的不是花括号,而是管道

为了证明这一点:

$ { ls && v=3; } > tmp
$ echo "$v"
3
引述:

在大多数shell中,管道的每个命令都在单独的子shell中执行

您可以使用变量来验证是否在子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
的值在外部不可用(从第二次输出中可以明显看出)

ooh,因此
v=1 | echo“hi”
将是相同的情况。是的,对
v
的更改将仅在子shell的生存期内持续。正确,因为
v=2;v=1 | echo“hi,v=$v”
返回“hi,v=2”。很有趣,非常感谢@看我的答案。这几乎是一样的。感谢你的技巧,anubhava,你总是会带来一些有趣的东西:)$BASHPID还可以用来获取shell实例的真实PID。
# 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 -