为什么在“while”循环中使用“读取变量”设置变量是全局的,而在使用“while 读取变量”设置时是局部变量?

Htt*_*tqm 0 bash shell-script variable

unset myVariable i;
while [ -z "$i" ]; do
    read myVariable;
    echo "myVariable : '$myVariable'";
    i=foo;
done;
echo "myVariable : '$myVariable'"
Run Code Online (Sandbox Code Playgroud)

unset是否允许重播命令)

按任意键 + ENTER,你会得到:

myVariable : '[what you typed]'
myVariable : '[what you typed]'
Run Code Online (Sandbox Code Playgroud)

的值myVariable存在于while循环之外。现在尝试:

tmpFile=$(mktemp);
echo -e 'foo\nbar\nbaz' >> "$tmpFile"
while read myVariable; do
    otherVariable=whatever; 
    echo "myVariable : '$myVariable', otherVariable : '$otherVariable'";
done < "$tmpFile";
echo "myVariable : '$myVariable', otherVariable : '$otherVariable'";
rm "$tmpFile"
Run Code Online (Sandbox Code Playgroud)

你会得到 :

myVariable : 'foo', otherVariable : 'whatever'
myVariable : 'bar', otherVariable : 'whatever'
myVariable : 'baz', otherVariable : 'whatever'
myVariable : '', otherVariable : 'whatever'
Run Code Online (Sandbox Code Playgroud)

myVariable离开循环时的值丢失。

为什么会有不同的行为?有没有我不知道的范围技巧?

注意:运行 GNU bash,版本 4.4.12(1)-release (x86_64-pc-linux-gnu)

ilk*_*chu 5

while read myVariable; do
Run Code Online (Sandbox Code Playgroud)

myVariable离开循环时的值丢失。

不,myVariable具有它从最后一个read. 脚本从文件中读取,直到它到达最后一个换行符之后的位置。之后,最终read调用从文件中获取任何信息,相应地设置myVariable为空字符串,并以假值退出,因为它没有看到分隔符(换行符)。然后循环结束。

read如果在最后一个换行符之后有不完整的行,您可以从最终获得一个非空值:

$ printf 'abc\ndef\nxxx' | 
    { while read a; do echo "got: $a"; done; echo "end: $a"; } 
got: abc
got: def
end: xxx
Run Code Online (Sandbox Code Playgroud)

或用于while read a || [ "$a" ]; do ...处理循环体内的最后一行片段。