(一)Shell的条件判断符及特殊变量

1 shell的条件判断

简单条件判断
条件测试通常有如下3中形式:

语法格式1:test<测试表达式>
语法格式2:[ <测试表达式> ]
语法格式3:[[ <测试表达式> ]]

说明:

  1. 上述语法格式1和语法格式2的写法是等价的。语法格式3为扩展的test命令,这里最好使用语法格式2。
  2. 在[[ ]]中可以使用通配符进行模式匹配。&&、||、>、<等操作符可以应用于[[ ]]中,但不能应用于[ ]中。
  3. 对于整数的关系运算,也可以使用Shell的算术运算符(())。
  4. 在写中括号表达式的时候括号里的两端要有至少一个空格。
  5. 这样的条件判断语句要比if语句更简洁,但是没有if语句更容易理解。

例子:

# 简单与或运算
[root@linux-node1 ~]# [ -e /etc/hosts ] && echo 0 || echo 1
0
[root@linux-node1 ~]# [ -e /etc/host ] && echo 0 || echo 1
1
# 这里注意 -e 参数是判断文件是否存在,Linux中一切皆文件
[root@linux-node1 ~]# [ -e /etc/ ] && echo 0    
0
[root@linux-node1 ~]# [ -f /etc/ ] && echo 0 || echo 1
1
[root@linux-node1 ~]# [ -d /etc/ ] && echo 0 || echo 1
0

# 可在大括号中包含多个命令
[root@linux-node1 scripts]# cat test1.sh
#!/bin/bash
[ $1 -eq 8 ] && {
  echo 1
  echo 1
  echo 1
}
[root@linux-node1 scripts]# bash test1.sh 8
1
1
1
[root@linux-node1 scripts]# bash test1.sh 9
[root@linux-node1 scripts]# 

1.1 按照文件类型进行判断

选项作用
-b 文件判断该文件是否存在,并且是否为块设备文件(是的为真)
-c 文件判断该文件是否存在,并且是否为字符设备文件(是的话为真)
-d 文件判断该文件是否存在,并且是否为目录文件(是的话为真)
-e 文件判断该文件是否存在(存在的话为真)
-f 文件判断该文件是否存在,并且是否为普通文件(是的话为真)
-L 文件判断该文件是否存在,并且是否为符号链接文件(是的话为真)
-p 文件判断该文件是否存在,并且是否为管道文件(是的话为真)
-s 文件判断该文件是否存在,并且是否为非空(是的话为真)
-S 文件判断该文件是否存在,并且是否为套接字文件(是的话为真)

1.2 按照文件权限进行判断

选项作用
-r 文件判断该文件是否存在,并且是否该文件拥有读权限(有为真)
-w 文件判断该文件是否存在,并且是否该文件拥有写权限(有为真)
-x 文件判断该文件是否存在,并且是否该文件拥有执行权限(有为真)
-u 文件判断该文件是否存在,并且是否该文件拥有SUID权限(有为真)
-g 文件判断该文件是否存在,并且是否该文件拥有SGID(有为真)
-k 文件判断该文件是否存在,并且是否该文件拥有Sbit(有为真)

1.3 两个文件之间进行比较

选项作用
文件1 -nt 文件2判断文件1的修改时间是否比文件2的新(若是则为真)
文件1 -ot 文件2判断文件1的修改时间是否比文件2的旧(若是则为真)
文件1 -ef 文件2判断文件1是否和文件2的inode号一致,可以理解为两个文件是否为同一个文件,这个判断用于判断硬链接是很好的方法

1.4 两个整数之间比较

选项作用
整数1 -eq 整数2判断整数1是否和整数2相等(相等为真)
整数1 -ne 整数2判断整数1是否和整数2不相等(不相等为真)
整数1 -gt 整数2判断整数1是否大于整数2(大于为真)
整数1 -lt 整数2判断整数1是否小于整数2(小于为真)
整数1 -ge 整数2判断整数1是否大于等于整数2(大于等于为真)
整数1 -le 整数2判断整数1是否小于等于整数2(小于等于为真)

eq ==> equal
ne ==> not equal
gt ==> greater than
lt ==> less than
ge ==> greater than or equal
le ==> less than or equal

测试:

[root@RSQ scripts]# [[ 3 -eq 2 ]]
[root@RSQ scripts]# echo $?
1
[root@RSQ scripts]# [[ 3 -eq 3 ]]
[root@RSQ scripts]# echo $?
0
[root@RSQ scripts]# [[ 3 = 3 ]]
[root@RSQ scripts]# echo $?
0
# 测试[[]]的大于符号,可以明显看出区别,只会顺位比较第一字符
[root@RSQ scripts]# [[ 3 > 2 ]]
[root@RSQ scripts]# echo $?
0
[root@RSQ scripts]# [[ 3 > 22 ]]
[root@RSQ scripts]# echo $?
0
[root@RSQ scripts]# [[ 3 > 111 ]]
[root@RSQ scripts]# echo $?
0
[root@RSQ scripts]# ((3>111))
[root@RSQ scripts]# echo $?
1
[root@RSQ scripts]# ((3<111))
[root@RSQ scripts]# echo $?
0

测试结果结论:

  1. 整数加双引号也是对的
  2. [[]]-eq等的写法也是对的;[[]]>写法也可能不对,它比较数值的第一位,逻辑结果不对。
  3. []>号的写法语法没错,逻辑结果不对。
    工作:使用[]-eq用法。

小结:

# 整数比较推荐下边用法:
[ $num -eq $num2 ]	#注意空格,和比较符号
(($num1>$num2))	#无需空格,常规数学比较符号

# 系统脚本例子
[root@linux-node1 ~]# grep -w "\-eq" /etc/init.d/nfs
        [ $RETVAL -eq 0 ] && RETVAL=$rval
                [ $RETVAL -eq 0 ] && RETVAL=$rval
                [ $RETVAL -eq 0 ] && RETVAL=$rval
        [ $RETVAL -eq 0 ] && RETVAL=$rval
                [ $RETVAL -eq 0 ] && RETVAL=$rval

1.5 字符串的判断

选项作用
-z “字符串”判断字符串是否为空(为空返回真)
-n “字符串”判断字符串是否为非空(非空返回真)
“字串1” == “字串2”判断字符串1是否和字符串2相等(相等返回真)
“字串1” != “字串2”判断字符串1是否和字符串2不相等(不相等返回真)

特别注意:

  1. 以上表格中的字符串测试操作符务必要用""引起来。
  2. 比较符号的两端必须有空格。

例子:

[root@linux-node1 ~]# [ -n "abc" ] && echo 0 || echo 1
0
[root@linux-node1 ~]# [ -z "abc" ] && echo 0 || echo 1
1
[root@linux-node1 ~]# [ ! -z "abc" ] && echo 0 || echo 1
0

# 系统脚本用法
[root@linux-node1 ~]# sed -n '30,31p' /etc/init.d/network 
# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 6

# 截取部分nfs启动脚本文件
[root@linux-node1 ~]# vim /etc/init.d/nfs
        [ -z "$MOUNTD_NFS_V2" ] && MOUNTD_NFS_V2=default
        [ -z "$MOUNTD_NFS_V3" ] && MOUNTD_NFS_V3=default

        # Number of servers to be started by default
        [ -z "$RPCNFSDCOUNT" ] && RPCNFSDCOUNT=8

1.6 多重条件判断

选项作用
判断1 -a 判断2逻辑与,判断1和判断2都成立,最终的结果才为真
判断1 -o 判断2逻辑或,判断1和判断2有一个成立,最终的结果就为真
! 判断逻辑非,是原始的判断是取反

提示:

!	中文意思是反:与一个逻辑值相反的逻辑值
-a	中文意思是与(and &&):两个逻辑值都为“真”,返回值才为“真”,反之为“假”
-o	中文意思是或(or ||):两个逻辑值之遥有一个为“真”,返回值就为“真”

逻辑操作符运算规则:

结论:-a和&&的运算规则:只有两端都是1才为真
真true 1
假false 0

例子:

[root@linux-node1 ~]# f1=/etc/rc.local;f2=/etc/services 

# 在[]单中括号中不能使用&&
[root@linux-node1 ~]# [ -f "$f1" && -f "$f2" ] && echo 1||echo 2   
-bash: [: missing `]'
2
[root@linux-node1 ~]# [ -f "$f1" -a -f "$f2" ] && echo 1||echo 2
1
[root@linux-node1 ~]# a=1
[root@linux-node1 ~]# b=2
[root@linux-node1 ~]# [ $a -eq 2 -a $b -eq 2 ] && echo 1||echo 0
0
[root@linux-node1 ~]# [ $a -eq 1 -a $b -eq 2 ] && echo 1||echo 0
1
[root@linux-node1 ~]# [ $a -eq 1 -o $b -eq 2 ] && echo 1||echo 0
1
[root@linux-node1 ~]# [ $a -eq 3 -o $b -eq 3 ] && echo 1||echo 0
0

# 系统脚本:
[root@linux-node1 ~]# sed -n '87,90p' /etc/init.d/nfs
        [ "$NFSD_MODULE" != "noload" -a -x /sbin/modprobe ] && {
                /sbin/modprobe nfsd
                [ -n "$RDMA_PORT" ] && /sbin/modprobe svcrdma
        }

小结:

  • []中用-a、-o、!
  • [[]]中用&&、||、!
  • test用法和[]相同
  • 多个[]之间以及多个[[]]之间,或者任意混合中间逻辑操作符都是&&或||

2 shell的特殊变量

$0 当前脚本的名字,如果包含路径则会一并输出
$n 传递给脚本或函数的参数,第n个参数值,n=1…9,若n大于就则需用{}括起来,如: 10 ‘ {10} ` 10*传递给脚本或函数的参数个数。此选项参数可超过9个。KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲` 传递给脚本或函数的所有参数… ‘ 当 前 S h e l l 进 程 I D ( 脚 本 运 行 的 当 前 进 程 I D 号 ) ‘ ` 当前Shell进程ID(脚本运行的当前进程ID号) ` ShellID(ID)!执行上一个指令的PID(后台运行的最后一个进程的进程ID号) ? ‘ 执 行 上 一 个 指 令 的 返 回 值 ( 显 示 最 后 命 令 的 退 出 状 态 。 0 表 示 没 有 错 误 , 其 他 任 何 值 表 明 有 错 误 ) ‘ ?` 执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误) ` ?(退0)-显示shell使用的当前选项,与set命令功能相同$_` 在此之前执行的命令或脚本的最后一个参数

2.1 $*$@ 的区别

$*

  • 所有的位置参数,被作为一个单词.
  • 注意:$*必须被""引用.

$@

  • $*同义,但是每个参数都是一个独立的""引用字串,这就意味着参数被完整地传递,并没有被解释和扩展,这也意味着每个参数列表中的每个参数都被当成一个独立的单词
    注意:$@必须被引用.
  • $@$*只在被双引号包起来的时候才会有差异

双引号括起来的情况:

  • $*将所有的参数认为是一个字段
  • $@以IFS(默认为空格)来划分字段,如果空格在" "里面,不划分
  • $@$*类似,但是可以当作数组用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RSQ博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值