我的bash版本是 GNU bash,版本4.3.42(1)-release(x86_64-pc-linux-gnu)。这是我的脚本的简化版本:
#!/bin/bash
touch a.ecl
touch b.ecl
function_syntaxCheckFileName()
{
return 1 # 1 syntax error
}
tmpTotalErrors=0
result=0
echo "DEBUG Starting loop"
find . -name '*.ecl' -print0 | while read -d $'\0' file
do
echo " DEBUG - FILE=$file"
echo " DEBUG0 tmpTotalErrors=$tmpTotalErrors --- result=$result"
function_syntaxCheckFileName "$file"
result=$?
echo " DEBUG1 tmpTotalErrors=$tmpTotalErrors --- result=$result"
tmpTotalErrors=$((tmpTotalErrors + result))
echo " DEBUG2 tmpTotalErrors=$tmpTotalErrors --- result=$result"
done
echo "DEBUG3 tmpTotalErrors=$tmpTotalErrors"
它被设计为在路径中使用空格运行,因此我使用此迭代
找到。 -name'* .ecl'-print0 |读取-d $'\ 0'文件
输出是:
DEBUG Starting loop
DEBUG - FILE=./a.ecl
DEBUG0 tmpTotalErrors=0 --- result=0
DEBUG1 tmpTotalErrors=0 --- result=1
DEBUG2 tmpTotalErrors=1 --- result=1
DEBUG - FILE=./b.ecl
DEBUG0 tmpTotalErrors=1 --- result=1
DEBUG1 tmpTotalErrors=1 --- result=1
DEBUG2 tmpTotalErrors=2 --- result=1
DEBUG3 tmpTotalErrors=0
我的问题是tmpTotalErrors失去了它的价值。它应该是2,它是0。
所以我的问题是:
答案 0 :(得分:3)
使用 set + m重写循环以避免使用subhel; shopt -s lastpipe
#!/bin/bash
set +m
shopt -s lastpipe
touch a.ecl
touch b.ecl
function_syntaxCheckFileName()
{
return 1 # 1 syntax error
}
tmpTotalErrors=0
result=0
echo "DEBUG Starting loop"
find . -name '*.ecl' -print0 | while read -d $'\0' file
do
echo " DEBUG - FILE=$file"
echo " DEBUG0 tmpTotalErrors=$tmpTotalErrors --- result=$result"
function_syntaxCheckFileName "$file"
result=$?
echo " DEBUG1 tmpTotalErrors=$tmpTotalErrors --- result=$result"
tmpTotalErrors=$((tmpTotalErrors + result))
echo " DEBUG2 tmpTotalErrors=$tmpTotalErrors --- result=$result"
done
echo "DEBUG3 tmpTotalErrors=$tmpTotalErrors"
它失败了,因为here中的更改不会反映在父shell中。
另请参阅此Bash常见问题解答条目:subshell,其中讨论了许多替代解决方案。