我已经读过您可以将I / O重定向到Bash中的各种结构(例如"如果"和#34;而#34;)。当我尝试这个时,我注意到使用" |"在if结构的末尾,阻止了我在if结构中覆盖的任何变量生效;但如果我使用">"相反,变量修改生效。
#!/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被改变?
答案 0 :(得分:1)
结帐Bash FAQ 24。 它会回答您的问题以及提供的示例!
您正在创建一个SubShell,而Process Substitution将与其父变量的副本一起被丢弃。
以下面的常见错误为例:
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"
输出:
var value inside subshell is: 1
But in the parent shell it stays: 0
当不希望这种行为时,解决方案通常是使用Bash FAQ 24来更新变量。因此,在我们的情况下(或通常在{{3}}中可以看到),我们执行以下操作:
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
答案 1 :(得分:0)
这是因为管道使用子壳;通过管道到cat
,你已经在子shell中执行了第一个if-then块。因此,VAR_0='Changed'
已更改,但仅在子shell中。
尝试:
#!/bin/bash
VAR_0='Unmodified'
if true
then
VAR_0='Changed'
echo "VAR_0: $VAR_0"
fi | cat
echo "VAR_0: $VAR_0"
重定向到文件(“>
”)不创建子shell;因此该变量仍然存在。