Linux用bash写脚本(2)

Linux用bash写脚本(2)

1.比较、对比、判断

在写脚本时,有时需要做一些比较,例如,两个数字谁大谁小,两个字符串是否相同等。做对比的表达式有[]、[[]]、test,其中[]和 test这两种表达式的作用是相同的。[[]]和[]的不同在于,[[]]能识别通配符和正则表达式中的元字符,[]却不能。
需要注意的是,在比较时,中括号和后续提及的比较符两边都要留有空格。

1.1数字的比较

数字的比较,主要是比较两个数字谁大谁小,或者是否相同。能用到的比较符有以下几种。

1)-eq:相等。
(2)-ne:不相等。
(3)-gt:大于。
(4)-ge:大于等于。
(5)-lt:小于。
(6)-le:小于等于。

做完比较之后,通过返回值来判断比较是否成立

[root@rh1 ~]# [ 1 -eq 2  ]
[root@rh1 ~]# echo $?
1

1是不能等于2的,所以判断不成立,返回值为非零。注意中括号和比较符两边的空格。

判断1不等于2,命令如下。

[root@rh1 ~]# [ 1 -ne 2 ]
[root@rh1 ~]# echo $?
0

1不等于2,所以判断成立,返回值为0。

1.2字符串的比较

字符串的比较,一般是比较两个字符串是否相同,用得较多的比较符有以下两种。

(1)==:相同。
(2)!=:不相同。
做完比较之后,通过返回值来判断比较是否成立。

定义一个变量aa=tom,然后做判断,命令如下。

[root@rh1 ~]# aa=tom
[root@rh1 ~]# [ $aa == tom ]
[root@rh1 ~]# echo $?
0

变量aa的值和 tom完全相同,所以判断成立,返回值为0。

在判断中匹配通配符,命令如下。

[root@rh1 ~]# aa=tom
[root@rh1 ~]# [ $aa == to? ]
[root@rh1 ~]# echo $?
1

这里定义aa=tom,按照前面讲过的通配符,to?匹配的应该是前两个字符为to,第三个可以是任意字符,所以 tom应该会被to?匹配到,为什么返回值为非零呢?

原因在于在这一对中括号[]中是不能识别通配符的,aa的值是t、o、m三个字符,而等号后面是t、o、?这三个字符,并没有把问号当成通配符,所以判断不成立。

如果想识别通配符,那么就要用双中括号[[]],看下面的判断。

[root@rh1 ~]# aa=tom
[root@rh1 ~]# [[ $aa == to? ]]
[root@rh1 ~]# echo $?
0

在[[]]中能识别通配符“?”,所以这里判断成立,返回值为0。

1.3属性的判断

属性的判断,用于判断一个文件是否具备某个属性,常见的属性包括以下7种。

(1)-r:具备读权限。
(2)-w:具备写权限。
(3)-x:具备可执行权限。

以上三个属性,不管是出现在u、g还是o上,只要有就算判断成立。

(4)-d:一个目录。
(5)-l:一个软链接。
(6)-f:一个普通文件,且要存在。
(7)-e:不管什么类型的文件,只要存在就算判断成立。

判断/etc/hosts具备r权限,命令如下。

[root@rh1 ~]# ls -l /etc/hosts
-rw-r--r--. 1 root root 158 9月  10 2018 /etc/hosts
[root@rh1 ~]# [ -r /etc/hosts ]
[root@rh1 ~]# echo $?
0

通过第一条命令可以看到/etc/hosts是具备r权限的,判断/etc/hosts具备r权限,自然成立,所以返回值为0。

判断/etc/hosts具备x权限,命令如下。

[root@rh1 ~]# [ -x /etc/hosts ]
[root@rh1 ~]# echo $?
1

这里判断/etc/hosts具备x权限,但是/etc/hosts不管是u、g还是o都不具备x权限,所以判断不成立,返回值为非零。
如果做一个否定判断,在前面加上叹号“!”即可。

判断/etc/hosts没有x权限,命令如下。

[root@rh1 ~]# [ ! -x /etc/hosts ]
[root@rh1 ~]# echo $?
0

这里判断/etc/hosts没有x权限,判断是成立的,所以返回值为0。

判断/etc是一个普通文件,命令如下。

[root@rh1 ~]# [ -f /etc ]
[root@rh1 ~]# echo $?
1

我们知道/etc是一个目录而不是一个文件,所以这个判断是不成立的,返回值为非零。

判断/etc不管是什么类型的,只判断存在还是不存在,命令如下。

[root@rh1 ~]# [ -e /etc/ ]
[root@rh1 ~]# echo $?
0

这里/etc是存在的目录,-e用于判断存在不存在,不判断文件类型,所以返回值为0。

1.4使用连接符

前面讲的判断只是单个判断,如果要同时做多个判断,那么就需要使用连接符了。能用的连接符包括“&&”和“||”。

先看一下使用&&作为连接符,用法如下。

判断1 && 判断2

只有两个判断都为真(返回值为0),整体才为真,只要有一个为假,整体就为假。判断1如果为假,判断2还有必要执行吗?没有,因为整体已经确定为假了。判断1为真,整体是真是假在于判断2,所以判断2肯定是要执行的。

[root@rh1 ~]# [ 1 -le 2 ] && [ 2 -ge 3 ]
[root@rh1 ~]# echo $?
1

这里有两个判断,第一个判断是1小于等于2,这个判断成立,第二个判断是2大于等于3,这个判断不成立。使用&&作为连接符,需要两边的判断都成立,整体才成立,所以整个判断为假,返回值为非零。

[root@rh1 ~]# [ 1 -le 2 ] && [ 2 -le 3 ]
[root@rh1 ~]# echo $?
0

这里有两个判断,第一个判断是1小于等于2,这个判断成立,第二个判断是2小于等于3,这个判断也成立。使用&&作为连接符,需要两边的判断都成立,整体才成立,所以整个判断为真,返回值为0。

下面看使用||作为连接符,用法如下。

判断1 || 判断2

两个判断只要有一个为真(返回值为0),整体就为真,只有全都为假,整体才为假。

[root@rh1 ~]# [ 1 -ge 2 ] || [ 2 -ge 3 ]
[root@rh1 ~]# echo $?
1

这里有两个判断,第一个判断是1大于等于2,第二个判断是2大于等于3,这两个判断都为假,所以整个判断为假,返回值为非零。

2.if判断语句

在脚本中执行某条命令需要满足一定的条件,如果不满足就不能执行。此时我们就要用到判断语句了。

先看if判断,if判断的语法如下。

if 条件1 ; then
命令1
elif 条件2 ; then
命令2
else 命令3
fi

先判断if后面的判断是不是成立。

如果成立,则执行命令1,然后跳到f后面,执行6后面的命令。

如果不成立,则不执行命令1,然后判断elif后面的条件2是不是成立。

如果成立,则执行命令2,然后跳到f后面,执行f后面的命令。

如果不成立,则不执行命令2,进行下一轮的elif 判断,以此类推。

如果所有if和elif都不成立,则执行clse中的命令3。

写一个脚本/opt/sc1.sh,要求只有root用户才能执行此脚本,其他用户不能执行,命令如下。

[root@rh1 opt]# cat /opt/sc1.sh
#/bin/bash
if [ $UID -ne 0 ]; then
echo "只有root才能执行此脚本"
exit 1
fi
echo "hello root"
[root@rh1 opt]# chmod +x /opt/sc1.sh

脚本分析如下。

root的uid是0,其他用户的uid不为0。第一个判断,如果uid不等于0,则打印警告信息“只有root才能执行此脚本”,然后exit退出脚本。

如果这里不加 exit,判断之后仍然会继续执行echo "hello root"命令,这样判断就失去了意义。只有加了exit之后,如果不是root,则到此结束,不要继续往下执行了。

如果是blab 执行此脚本,则判断成立,打印完警告信息之后,通过exit退出脚本。

如果是 root执行此脚本,则判断不成立,直接执行f后面的命令。

使用root用户执行此脚本的结果如下。

[root@rh1 opt]# /opt/sc1.sh
hello root

使用bdqn用户执行此脚本的结果如下。

[bdqn@rh1 ~]$ /opt/sc1.sh
只有root才能执行此脚本

写一个脚本 lopt/sc2.sh,运行脚本时,后面必须跟一个参数,参数是系统中的一个文件。

如果这个文件不存在,则显示该文件不存在;如果存在,则显示该文件的行数,命令如下。

[root@rh1 opt]# cat /opt/sc2.sh
#!/bin/bash
if [ $# -eq 0 ] ; then
echo "脚本后面必须跟一个参数"
exit 1
fi
if [ -f $1 ] ; then
wc -l $1
else
echo "$1不存在"
fi
[root@rh1 opt]# chmod +x /opt/sc2.sh

脚本分析如下。

KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲表示参数的个数,第一个判断中,#的值如果等于0,则说明脚本后面没有跟任何参数,打印“脚本后面必须跟一个参数”,然后退出脚本。

如果后面跟了参数,则第一个判断不成立,然后进行下一个if判断。

第一个参数用$1来表示,[ -f $1 ]用于判断所跟的参数是不是存在,如果存在则执行wc-1 $1命令,如果不存在则执行else 中的命令。
运行脚本,效果如下

[root@rh1 opt]# /opt/sc2.sh 
脚本后面必须跟一个参数

这次运行没有跟任何参数,则提示必须跟一个参数。

[root@rh1 opt]# /opt/sc2.sh /etc/hostsxxx
/etc/hostsxxx不存在

这里跟了一个不存在的文件/etc/hostsxxx,脚本提示这个文件不存在。

[root@rh1 opt]# /opt/sc2.sh /etc/hosts
2 /etc/hosts

1命令,如果不存在则执行else 中的命令。
运行脚本,效果如下

[root@rh1 opt]# /opt/sc2.sh 
脚本后面必须跟一个参数

这次运行没有跟任何参数,则提示必须跟一个参数。

[root@rh1 opt]# /opt/sc2.sh /etc/hostsxxx
/etc/hostsxxx不存在

这里跟了一个不存在的文件/etc/hostsxxx,脚本提示这个文件不存在。

[root@rh1 opt]# /opt/sc2.sh /etc/hosts
2 /etc/hosts

这次脚本后面跟了一个存在的文件/etc/hosts,脚本会显示该文件的行数,为2行。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值