使用'|';来自Bash';s if构造阻止设置变量
我已经读到,您可以将I/O重定向到Bash中的各种构造中或从中重定向出来(例如“if”和“while”)。当我尝试这一点时,我注意到在if构造的末尾使用“|”会阻止我在if构造中过度编写的任何变量生效;但是如果我使用“>”,那么变量修改就会生效使用'|';来自Bash';s if构造阻止设置变量,bash,if-statement,pipe,pipeline,Bash,If Statement,Pipe,Pipeline,我已经读到,您可以将I/O重定向到Bash中的各种构造中或从中重定向出来(例如“if”和“while”)。当我尝试这一点时,我注意到在if构造的末尾使用“|”会阻止我在if构造中过度编写的任何变量生效;但是如果我使用“>”,那么变量修改就会生效 #!/bin/bash VAR_0='Unmodified' if true then VAR_0='Changed' fi | cat echo "VAR_0: $VAR_0" ########### VAR_1='Unmodifie
#!/bin/bash
VAR_0='Unmodified'
if true
then
VAR_0='Changed'
fi | cat
echo "VAR_0: $VAR_0"
###########
VAR_1='Unmodified'
if true
then
VAR_1='Changed'
fi > tmpFile
rm tmpFile
echo "VAR_1: $VAR_1"
在64位Linux上运行Bash版本4.3.11会产生以下输出:
VAR_0: Unmodified
VAR_1: Changed
注意,唯一的区别是如何从if构造重定向stdout。为什么“|”阻止VAR_0被更改?这是因为管道使用子shell;通过管道传输到
cat
,您已经在子shell中执行了第一个if-then块。因此,VAR\u 0='Changed'
被更改,但仅在子shell中更改
尝试:
重定向到文件(“
”)不会创建子shell;因此,该变量持续存在。TL;博士
退房。
它与提供的示例一起回答您的问题
您正在创建一个脚本,该脚本将与其父shell的变量副本一起丢弃 以以下常见错误为例:
var=0
some-command | while read -r line; do
printf 'var value inside subshell is: %s\n' "$((++var))"
done
printf 'But in the parent shell it stays: %s\n' "$var"
输出:
当不需要这个behvior时,通常使用解决方案来更新变量。因此,在我们的情况下(或从中可以普遍看出),我们做了以下工作:
var=0
while read -r line; do
printf 'var value inside subshell is: %s\n' "$((++var))"
done < <(some-command)
printf 'And it stays the same: %s\n' "$var"
var value inside subshell is: 1
But in the parent shell it stays: 0
var=0
while read -r line; do
printf 'var value inside subshell is: %s\n' "$((++var))"
done < <(some-command)
printf 'And it stays the same: %s\n' "$var"
var value inside subshell is: 1
And it stays the same: 1