Closed vieyahn2017 closed 5 years ago
-e filename 如果 filename存在,则为真 -d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真 -L filename 如果 filename为符号链接,则为真 -r filename 如果 filename可读,则为真 -w filename 如果 filename可写,则为真 -x filename 如果 filename可执行,则为真 -s filename 如果文件长度不为0,则为真 -h filename 如果文件是软链接,则为真 filename1 -nt filename2 如果 filename1比 filename2新,则为真。 filename1 -ot filename2 如果 filename1比 filename2旧,则为真。
-eq 等于 -ne 不等于 -gt 大于 -ge 大于等于 -lt 小于 -le 小于等于
If [ $a = $b ] 如果string1等于string2,则为真
字符串允许使用赋值号做等号
if [ $string1 != $string2 ] 如果string1不等于string2,则为真
if [ -n $string ] 如果string 非空(非0),返回0(true)
if [ -z $string ] 如果string 为空,则为真
if [ $sting ] 如果string 非空,返回0 (和-n类似)
逻辑非 ! 条件表达式的相反 if [ ! 表达式 ] if [ ! -d $num ] 如果不存在目录$num
逻辑与 –a 条件表达式的并列 if [ 表达式1 –a 表达式2 ]
逻辑或 -o 条件表达式的或 if [ 表达式1 –o 表达式2 ]
[ -z STRING ] “STRING” 的长度为零则为真。
[ -n STRING ] or [ STRING ] “STRING” 的长度为非零 non-zero则为真。
https://blog.csdn.net/keep_lcm/article/details/80551435
应用场景分析:
-z 判断 变量的值,是否为空; zero = 0
- 变量的值,为空,返回0,为true
- 变量的值,非空,返回1,为false
-n 判断变量的值,是否为空 name = 名字
- 变量的值,为空,返回1,为false
- 变量的值,非空,返回0,为true
pid="123"
[ -z "$pid" ] 单对中括号变量必须要加双引号
[[ -z $pid ]] 双对括号,变量不用加双引号
[ -n "$pid" ] 单对中括号,变量必须要加双引号
[[ -z $pid ]] 双对中括号,变量不用加双引号
2.1:[[ ]] 双对中括号,是不能使用 -a 或者 -o的参数进行比较的;
&& 并且 || 或 -a 并且 -o 或者
[[ ]] 条件判断 && 并且 || 或
[[ 5 -lt 3 || 3 -gt 6 ]] 一个条件,满足,就成立 或者的关系
[[ 5 -lt 3 || 3 -gt 6 ]] 一个条件满足,就成立 或者的关系
[[ 5 -lt 3 ]] || [[3 -gt 6 ]]
[[ 5 -lt 3 ]] || [[3 -gt 6 ]] 写在外面也可以
&& 必须两个条件同时满足,和上述一样,这里想说明的问题的是:
[[ 5 -lt 3]] -o [[ 3 -gt 6 ]] [[ 5 -lt 3 -o 3 -gt 6 ]]
[[ 5 -lt 3 -a 3 -gt 6 ]] [[ 5 -lt 3 -a 3 -gt 6 ]]
-a 和 -o就不成立了,是因为,[[]] 双对中括号,不能使用 -o和 -a的参数
直接报错:
2.2 [ ] 可以使用 -a -o的参数,但是必须在 [ ] 中括号内,判断条件,例如:
[ 5 -lt 3 -o 3 -gt 2 ] 或者条件成立
[5 -lt 3 ] -o [ 3 -gt 2] 或者条件, 这个不成立,因为必须在中括号内判断
如果想在中括号外判断两个条件,必须用&& 和 || 比较
[5 -lt 3 ] || [ 3 -gt 2]
[5 -gt 3 ] && [ 3 -gt 2] 成立
相对的,|| 和 && 不能在中括号内使用,只能在中括号外使用
$ tel=13612345678
$ [[ $tel =~ [0-9]{11} ]]
$ echo $?
0
$ [ $tel =~ [0-9]{11} ]
bash: [: =~: binary operator expected
单对中括号,直接报错
这有篇记录了现象,原因分析是错误的一篇文章
https://blog.csdn.net/u011259594/article/details/46402001
千里之行,始于足下。未来几年里希望这个博客能一直坚持写下去。
正文 在学习shell脚本时发现在做if判断时,对于空字符串的判断上-n做出了一些错误的判定,以下是测试过程,不愿细看的请直接跳转到文章最后看结果。
出错代码如下
a=""
if [ -z $a ]
then
echo "Length of a: \"$a\" is zero "
else
echo "Length of a: \"$a\" is not zero "
fi
if [ -n $a ]
then
echo "Length of a: \"$a\" is not zero "
else
echo "Length of a: \"$a\" is zero "
fi
输出:
Length of a: "" is zero
Length of a: "" is not zero
显然答案是错误的。
有趣的是,将$a两边加上引号变成 "$a" 后,结果却出乎意料的正确了。
a=""
if [ -z "$a" ]
then
echo "Length of a: \"$a\" is zero "
else
echo "Length of a: \"$a\" is not zero "
fi
if [ -n "$a" ]
then
echo "Length of a: \"$a\" is not zero "
else
echo "Length of a: \"$a\" is zero "
fi
```sh
输出:
Length of a: "" is zero
Length of a: "" is zero
这次的输出是正确的。
因此我们可以大胆猜测,可能是因为a=""时,编译器并未识别成字符串从而导致-n判断失误
通过查找shell的源码coreutils-8.23中的test.c发现
```c
switch (argv[pos][1])
{
...
case 'n': /* True if arg has some length. */
unary_advance ();
return argv[pos - 1][0] != 0;
case 'z': /* True if arg has no length. */
unary_advance ();
return argv[pos - 1][0] == '\0';
...
}
结论 -z的判断是通过判断字符串首位是否为\0来完成,而-n则变成了0,笔者猜测就是这个细微的差别造成了结果的不同。 在查阅所有相关源码之后,我并没找到更深层的原因,暂时只能给出解决办法。即: 在处理字符串时,-n参数是有bug的,若要判断a是否为空需要使用
if [ "$a+x" = "x" ]
将来如果有更多发现,将在本文下更新,也欢迎留言交流
因为遇到了同样的错误,找到了您的这篇文章,不过参考其他的搜索结果,我的理解稍微有些不同, 参考:https://blog.csdn.net/ciky2011/article/details/37876119 , 在 if [ -n $a ] 这种情况,如果 $a 是空,实际是按照 if [ -n ] 来判断了,这种情况下,-n 成了作为判断的字符串,所以返回了 True, 类似的随便写一个字符串 if [ -tdsfadsfa ],是返回 True 的,使用加引号的方式,或者 if [[ -n $a ]] 可以避免这种情况(6个月前#1楼)
linux 下shell中if的“-e,-d,-f”是什么意思 https://www.cnblogs.com/senior-engineer/p/6206329.html