我有这个 bash 脚本:
#!/bin/bash
someVar=0
tac /etc/hosts | while IFS= read line; do
echo "$someVar : $line"
someVar=$((someVar+1))
done
echo "Finally: $someVar"
当我使用 运行它时./test.sh
,我得到以下输出:
0 : ::1 localhost ipv6-localhost ipv6-loopback
1 : fe00::0 ipv6-localnet
2 : ff00::0 ipv6-mcastprefix
Finally: 0
为什么 varsomeVar
末尾是 0,即使之前是 2,即使如上所述这里它应该是全局的,并且在 var 增加之前就执行得很好?
答案1
为什么 var someVar 末尾是 0?
someVar 的修改是局部的(由管道导致的子外壳程序)。
$ shellcheck myscript
Line 5:
tac /etc/hosts | while IFS= read line; do
^-- SC2162 (info): read without -r will mangle backslashes.
Line 7:
someVar=$((someVar+1))
^-- SC2030 (info): Modification of someVar is local (to subshell caused by pipeline).
Line 9:
echo "Finally: $someVar"
^-- SC2031 (info): someVar was modified in a subshell. That change might be lost.
$
答案2
我找到了答案。
我们不用创建子 shell |
,而是可以在最后注入它。它无法与基本一起使用< $(cmd)
,但可以< <(cmd)
正常工作。
最终的脚本是这样的:
#!/bin/bash
someVar=0
while IFS= read line; do
echo "$someVar : $line"
someVar=$((someVar+1))
done < <(tac /etc/hosts) # <---- changes here
echo "Finally: $someVar"
输出:
0 : ::1 localhost ipv6-localhost ipv6-loopback
1 : fe00::0 ipv6-localnet
2 : ff00::0 ipv6-mcastprefix
Finally: 3 # not 0 !