我想制作一个构建链脚本,如果在编译过程中出现错误,我不希望它执行到最后。
这是我第一次在bash中编写一个更“详细”的脚本,它只是不起作用:
这是代码:
testError=false
output=$(scons)
while read -r line; do
if [[ $line == .*[eE]rror.* ]] ; then echo 'ERROR' ; $testError = true ; fi #$testError = true fi
done
echo $testError
if $testError ; then exit ; fi;
... other commands
编辑:关注所有海报答案以及Bash setting a global variable inside a loop and retaining its value -- Or process substituion for dummies和How do I use regular expressions in bash scripts?, 这是代码的最终版本。 它有效:
testError=false
shopt -s lastpipe
scons | while read -r line; do
if [[ $line =~ .*[eE]rror.* ]] ; then
echo -e 'ERROR'
testError=true
fi
echo -e '.'
done
if $testError ; then
set -e
fi
答案 0 :(得分:2)
您在管道引起的子shell中设置testError
的值。当子shell退出时(在管道的末尾),您所做的任何更改都会消失。试试这个:
while read -r line; do
if [[ $line == .*[eE]rror.* ]] ; then
echo -e 'ERROR'
testError=true
fi #$testError = true fi
done < <( scons )
或者,如果您不想或不能使用进程替换,请使用临时文件
scons > tmp
while read -r line; do
if [[ $line == .*[eE]rror.* ]] ; then
echo -e 'ERROR'
testError=true
fi #$testError = true fi
done < tmp
这消除了管道,因此对testError
的更改在while循环后仍然存在。
而且,如果您的bash版本足够新(4.2或更高版本),则有一个选项允许管道末尾的while循环在当前shell中执行,而不是子shell。
shopt -s lastpipe
scons | while read -r line; do
if [[ $line == .*[eE]rror.* ]] ; then
echo -e 'ERROR'
testError=true
fi #$testError = true fi
done
答案 1 :(得分:1)
你应该试试
set -e
如果命令以非零状态退出
,则会停止脚本继续运行或更好
error_case() { # do something special; }
trap 'echo >&2 "an error occurs"; error_case' ERR
每次命令退出非零状态时,运行error_case
函数
答案 2 :(得分:1)
您是否正在尝试解析scons的输出?
此:
output=$(scons)
while read -r line; do
if [[ $line == .*[eE]rror.* ]] ; then
echo 'ERROR'
testError=true
fi
done
不这样做。也许你想要:
scons | while read -r line; do ... ; done
答案 3 :(得分:1)
另一个错误是你在作业中有空格。并跳过$
$testError = true
应该是
testError=true
修改的
在子shell中更改了testerror。尝试
testerror=$(
scons | while read -r line; do
if [[ $line == .*[eE]rror.* ]] ; then
echo true
fi #$testError = true fi
done
)
答案 4 :(得分:0)
我也回答,因为其他答案没有注意到:使用=~
而不是==
这样使用正则表达式:
if [[ $line =~ .*[eE]rror.* ]] ; then
...