逻辑运算符在Shell脚本编程中的应用

原文发表于2017年第11期《网络安全与信息化》,转发到博客

在Linux系统运维工作中,Shell脚本编程是运维人员应必须掌握的一项基本技能,在大多数的Shell脚本中都需要进行条件测试操作,从而使得脚本可以有选择地执行任务。本文将介绍如何通过逻辑运算符来同时测试多个条件,以及如何利用逻辑运算符来连接多条命令,从而实现简单高效的选择判断操作。

1. 逻辑运算符的基本用法

通过逻辑运算符可以同时测试多个条件,根据这些条件是否同时成立或者只要有其中一个条件成立等情况,来决定采取何种操作。逻辑运算符有:  &&:逻辑与,表示前后两个条件都成立时整个测试结果才为真,否则结果为假。  ||:逻辑或,表示前后两个条件至少有一个成立时整个测试结果即为真,否则结果为假。  !:逻辑非,表示当指定的条件不成立时,整个测试结果为真。 逻辑运算符的基本用法非常简单,比如判断文件“/etc/passwd”和“/etc/shadow”是否存在,要求两个条件同时满足,则可以使用下面的表达式,并通过查看“$?”的值来获知测试结果,值为0表示条件成立,值为非0表示条件不成立。 [root@Server ~]# [ -e /etc/passwd ] && [ -e /etc/shadow ] [root@Server ~]# echo $? 0 再比如要测试当前用户文件“/etc/passwd”和“/etc/shadow”是否具有写入权限,只要满足其中一个条件即可,可以使用下面的表达式。 [root@Server ~]# [ -w /etc/passwd ] || [ -w /etc/shadow ] [root@Server ~]# echo $? 0

2. 逻辑运算符连接多条命令

除了同时测试多个条件之外,逻辑运算符“&&”和“||”通常也用于间隔不同的命令操作,这也是本文要重点介绍的内容。比如表达式“command1 && command2”,在这个表达式中,如果command1的测试结果为假,那么command2就不会再执行。因为对于逻辑与操作,只要有一个测试条件不成立,那么整个测试结果也就必然为假,因而此时就无需再去判断command2是否成立。反之,如果command1的测试结果为真,则command2就必须执行。 如果使用逻辑运算符“||”来连接两个命令,情况又是不同。比如表达式“command1 || command2”,在这个表达式中,如果command1的测试结果为真,则command2不再执行。因为对于逻辑或操作,只要有一个测试条件成立,那么整个测试结果就必然为真,因而此时也无需再去判断command2是否为真。反之,如果command1的测试结果为假,则command2必须执行。 因而,对于“&&”和“||”的特点可以总结如下:  &&,当前面的命令执行成功后才会执行后面的命令;  ||,当前面的命令执行失败后才会执行后面的命令。

3. 实例演示

下面是几个具体的应用实例。 例:判断当前的用户是否是teacher,若不是则提示“Not teacher”。 [root@localhost ~]# echo $USER root [root@localhost ~]# [ $USER = "teacher" ] || echo "Not teacher" Not teacher 例:判断当前的用户是否是teacher,若是则提示“Good Morning teacher”,若不是则提示“Not teacher”。 [root@localhost ~]# echo $USER root [root@localhost ~]# [ $USER = "teacher" ] && echo "Good morning teacher" || echo "not teacher" not teacher 同样是上面这个操作,我们切换到teacher用户再来试一下。 [root@localhost ~]# useradd teacher [root@localhost ~]# su - teacher [teacher@localhost ~]$ [ $USER = "teacher" ] && echo "Good morning teacher" || echo "not teacher" Good morning teacher 在这三个逻辑运算符中,“&&”尤为常用。比如要查看一个条件表达式的测试结果,如果通过查看预定义变量“$?”的值来进行判断,操作繁琐,输出结果也不是很直观。为了更便于查看条件测试操作的结果,通常都是将“&&”和echo命令一起使用,当条件成立时直接输出“yes”。 例:判断文件“/dev/cdrom”是否存在,如果存在,则直接输出yes。 [root@localhost ~]# [ -e /dev/cdrom ] && echo "yes" yes 例:只要“/etc/rc.d/rc.local”或者“/etc/init.d/rc.local”中有一个文件,则显示“YES”,否则无任何输出。 [root@localhost ~]# [ -f /etc/rc.d/rc.local ] || [ -f /etc/init.d/rc.local ] && echo "yes" 例:测试“/etc/profile”文件是否有可执行权限,若确实没有可执行权限,则提示“No x mode”的信息。 [root@localhost ~]# [ ! -x "etc/profile" ] && echo "No x mode" No x mode 例:若当前用户是root且使用的shell程序是“/bin/bash”,则显示“yes”,否则无任何输出。 [root@localhost ~]# [ $USER = "root" ] && [ $SHELL = "/bin/bash" ] && echo "yes" Yes 下面来编写一个具体的脚本,要实现的功能删除“/root/test”目录中的test-1、test-2……test-10文件,但是test-3和test-7除外。 在脚本中用到了for循环和continue语句,continue语句在for循环中用于暂停本次操作,跳转至循环语句的顶部重新测试条件,本次执行过程中continue后的命令序列将被忽略。 [root@localhost ~]# ls /root/test test-1 test-10 test-2 test-3 test-4 test-5 test-6 test-7 test-8 test-9 [root@localhost ~]# vim del.sh #!/bin/bash for i in $(seq 10) do #遇到需要保留的文件时跳过而不删除 [ $i -eq 3 ] || [ $i -eq 7 ] && continue rm -f /root/test/test-$i done [root@localhost ~]# chmod u+x del.sh [root@localhost ~]# ./del.sh [root@localhost ~]# ls /root/test test-3 test-7 因而,灵活运用 “&&”和“||”这两个逻辑运算符,在很多时候就可以代替复杂的if语句,从而使得我们的Shell脚本更加简捷高效。

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...