今天晚上在看测试系统安装的问题,脚本安装是成功的,但是我自己手动make却是失败的;仔细研究发现是test表达式的误用,这个bug都存在系统中好几年了,^_^
用的是Bash,其中一个函数如下:
function install_tet()
{
local ret=0
local temp_file=mktemp
cd $XVS_HG_REPO/validation/dependencies/tet/
make > $temp_file 2>&1 || ret=1
file_tet_rpm=$(grep "RPMS" $temp_file | grep -v "SRPMS" | grep -v "tet_testsuite_dependency-debuginfo" | awk '{print $NF}')
run_quiet rpm -ivh $file_tet_rpm --nodeps
run_quiet cd -
if [ $? -a $ret ];then
return 0
fi
return 1
}
看出什么问题了吗?
我手动直接执行cd $XVS_HG_REPO/validation/dependencies/tet/,然后执行make命令,其实是报错了的,其错误信息如下:
error: File /root/rpmbuild/SOURCES/tet_testsuite_dependency-3.3.2.tgz: No such file or directory
我们先不管导致这个错误的原因(其实是rhel6中rpmbuild的一些东西和rhel5u5中不一致,而我们脚本以前都是基于rhel5的)。
手动执行make命令都错误了,然后如果脚本自动运行却提示为install_tet函数是执行成功的(我们将return 0标志执行成功)。
经过仔细分析就会发现,函数中return 1是永远不可能执行到的,就不管函数执行过程中有没有错误发生,都会永远return 0.
那么问题的根本原因就浮出水面了,是下面这小段条件表达式的test的问题。
if [ $? -a $ret ];then
return 0
fi
如下的几段代码,都会return 0:
if [ 0 -a 0 ]; then
return 0
fi
if [ 1 -a 1 ]; then
return 0
fi
if [ false ]; then
return 0
fi
而下面两种情况是会return 1的:
if [ ]; then
return 0
else
return 1
fi
if test ''; then
return 0
else
return 1
fi
总结一下吧:
test某个条件表达式结果的真假,条件表达式必须进行了某个测试,例如-eq, -d等;也就是说一个表达式,无论是数字、字符串,test的结果都是true,例如
S=0
test $S
无论S取值什么都是true。但是如果 test $S -eq $S2,即用到了test所支持的表达式有了真假。
test(即[])没有参数时,会返回1(表示false);只有一个参数时,当且仅当该参数为空时,才会返回1.
更多详细信息,可以man bash找到 test expr处有详细的说明:
test expr
[ expr ]
Return a status of 0 or 1 depending on the evaluation of the conditional expression
expr. Each operator and operand must be a separate argument. Expressions are com-
posed of the primaries described above under CONDITIONAL EXPRESSIONS. test does not
accept any options, nor does it accept and ignore an argument of -- as signifying
the end of options.
Expressions may be combined using the following operators, listed in decreasing
order of precedence. The evaluation depends on the number of arguments; see below.
! expr True if expr is false.
( expr )
Returns the value of expr. This may be used to override the normal prece-
dence of operators.
expr1 -a expr2
True if both expr1 and expr2 are true.
expr1 -o expr2
True if either expr1 or expr2 is true.
test and [ evaluate conditional expressions using a set of rules based on the number
of arguments.
0 arguments
The expression is false.
1 argument
The expression is true if and only if the argument is not null.
2 arguments
If the first argument is !, the expression is true if and only if the second
argument is null. If the first argument is one of the unary conditional
operators listed above under CONDITIONAL EXPRESSIONS, the expression is true
if the unary test is true. If the first argument is not a valid unary condi-
tional operator, the expression is false.
3 arguments
If the second argument is one of the binary conditional operators listed
above under CONDITIONAL EXPRESSIONS, the result of the expression is the
result of the binary test using the first and third arguments as operands.
The -a and -o operators are considered binary operators when there are three
arguments. If the first argument is !, the value is the negation of the two-
argument test using the second and third arguments. If the first argument is
exactly ( and the third argument is exactly ), the result is the one-argument
test of the second argument. Otherwise, the expression is false.
4 arguments
If the first argument is !, the result is the negation of the three-argument
expression composed of the remaining arguments. Otherwise, the expression is
parsed and evaluated according to precedence using the rules listed above.
5 or more arguments
The expression is parsed and evaluated according to precedence using the
rules listed above.