shell if条件语句与字符比较实例教程

发布时间:2020-12-22编辑:脚本学堂
本文介绍了shell if语句的用法,shell if语句的参数说明,shell比较字符写法,shell test命令进行条件判断与检测的例子。

shell if语句测试条件
测试条件返回真(0)或假(1)后,可相应执行一系列语句。

if语句结构对错误检查非常有用。

其格式为:
if 条件1
then 命令1
elif 条件2
then 命令2
else
命令3
fi

shell if语句参数:
 

–b 当file存在并且是块文件时返回真
-c 当file存在并且是字符文件时返回真
-d 当pathname存在并且是一个目录时返回真
-e 当pathname指定的文件或目录存在时返回真
-f 当file存在并且是正规文件时返回真
-g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
-h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
-k 当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真
-p 当file存在并且是命令管道时返回为真
-r 当由pathname指定的文件或目录存在并且可读时返回为真
-s 当file存在文件大小大于0时返回真
-u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真
-w 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
-o 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。

shell比较字符写法:
 

-eq等于
-ne 不等于
-gt 大于
-lt 小于
-le 小于等于
-ge大于等于
-z 空串
=  两个字符相等
!= 两个字符不等
-n 非空串

更为详细的说明:
运算符描述 示例
1、文件比较运算符
 

-e filename  如果 filename 存在,则为真  [ -e /var/log/syslog ]
-d filename  如果 filename 为目录,则为真[ -d /tmp/mydir ]
-f filename  如果 filename 为常规文件,则为真[ -f /usr/bin/grep ]
-L filename  如果 filename 为符号链接,则为真[ -L /usr/bin/grep ]
-r filename  如果 filename 可读,则为真  [ -r /var/log/syslog ]
-w filename  如果 filename 可写,则为真  [ -w /var/mytmp.txt ]
-x filename  如果 filename 可执行,则为真[ -L /usr/bin/grep ]
filename1 -nt filename2 如果 filename1 比 filename2 新,则为真 [ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2如果 filename1 比 filename2 旧,则为真  [ /boot/bzImage -ot arch/i386/boot/bzImage ]

2、字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法)
 

-z string如果 string 长度为零,则为真[ -z $myvar ]
-n string如果 string 长度非零,则为真 [ -n $myvar ]
string1 = string2  如果 string1 与 string2 相同,则为真  [ $myvar = one two three ]
string1 != string2 如果 string1 与 string2 不同,则为真  [ $myvar != one two three ]

3、算术比较运算符
 

num1 -eq num2等于  [ 3 -eq $mynum ]
num1 -ne num2不等于[ 3 -ne $mynum ]
num1 -lt num2小于 [ 3 -lt $mynum ]
num1 -le num2  小于或等于  [ 3 -le $mynum ]
num1 -gt num2大于[ 3 -gt $mynum ]
num1 -ge num2大于或等于 [ 3 -ge $mynum ]
 

变量:("")双引号:用于标记多个特殊符号,但是对$,,`,!符号例外
('')单引号:作用同上,但是可以标记""所不能的特殊符号
(``)反引号[!前的那个符号,不是单引号]一般用来执行命令
()反斜杠:转义符号,用于标记单个特殊符号.
 

[root@redhat ~]# winner=bob
[root@redhat ~]# notice="the person who won is $winner"
[root@redhat ~]# echo $notice
the person who won is bob ##将$winner解析成变量
[root@redhat ~]# winner=bob
[root@redhat ~]# notice='the person who won is $winner'
[root@redhat ~]# echo $notice
the person who won is $winner ##$winner只是符号
[root@redhat ~]# echo $winner
bob
[root@redhat ~]# winner=bob
[root@redhat ~]# notice="the person who won is $winner"
[root@redhat ~]# echo $notice
the person who won is $winner ##用将$转义成字符
[root@redhat ~]# echo $winner
bob
[root@redhat ~]# listnew='ls *.new'
[root@redhat ~]# echo $listnew
ls main.cf.new master.cf.new ##仔细查看,两个结果不一样的
[root@redhat ~]# listnew=`ls *.new`
[root@redhat ~]# echo $listnew
main.cf.new master.cf.new

字符:空格(space): 解析命令行参数
(*)(?)({and}):产生文件名列表
(.): 代表当前目录
($): 对变量求值
(>)(<):重定向标准输入或输出
(&): 执行后台命令
(|): 管道输出
一般命令:echo 显示变量及字符
read 从用户处接受输入
<<输入重定向
脚本命令相关:$0 linuxcmd/ target=_blank class=infotextkey>linux命令名
$n 命令行参数
$* 由号码1开始的所有的命令行参数
$@ 分别访问命令行参数
$# 命令参数的个数
运算:exprort 将局部变量导出为该shell中的全局变量
+,-,*,/,>,<,>=,<=,=(用于字符串的比较),==(用于数字的比较),!=,&(与),|(或),!(非).[root@redhat ~]# let a=2*7
 

[root@redhat ~]# echo $a
14
[root@redhat ~]# let a="2 * 7"
[root@redhat ~]# echo $a
14

test比较运算,在比较运算中,正确结果的返回值是0,而不是传统程序上的1
 

-gt 一个数是否大于另一个数
-lt 小于
-ge 大于等于
-le 小于等于
-eq 等于(用于数值)
-ne 不等于
-z 是否为空字符串
-n 字符串是否大于0
=  字符串是否相等
!= 是否不等
str 是否非空
-a  与
-o 或
!  非
-f 是否为普通文件
-s 文件是否为空
-r 文件是否可读
-w 文件是否可写
-x 文件是否可执行
-d 是否为目录
-h 是否为符号链接
-c 是否与字符设备相关联
-b 是否与块文件相关联[root@redhat ~]# num=5
[root@redhat ~]# test $num -eq 10
[root@redhat ~]# echo $?
1 ##返回比较的结果值
[root@redhat ~]# num=5
[root@redhat ~]# test $num -eq 5
[root@redhat ~]# echo $?
0
 

下面的[]符号和test的作用等同[root@redhat ~]# num=5
 

[root@redhat ~]# [ $num -eq 10 ] ##注意中间空格的地方
[root@redhat ~]# echo $?
1
[root@redhat ~]# num=5
[root@redhat ~]# [ $num -eq 5 ]
[root@redhat ~]# echo $?
0

分享一例测试脚本:
 

[root@redhat ~]# vi lss.sh
#!/bin/bash ##使用bash
echo This is a list Bash Script
echo S: list sizes
echo L: List all file information
echo C: list c Files
echo -n "Please enther choice:"
read choice ##等待用户输入
case $choice in
s|S)##如果输入的是s,不区分大小写
ls -s
;;
l|L) ##如果输入的是l,不区分大小写
ls -l
;;
c|C) ##如果输入的是c,不区分大小写
ls *.new
;;
*) ##都不是的话
echo error
esac
[root@redhat ~]# chmod +x lss.sh
[root@redhat ~]# ./lss.sh
This is a list Bash Script
S: list sizes
L: List all file information
C: list c Files
Please enther choice:l
total 69
-rw-r--r-- 1 root root 1251 Oct 24 15:01 anaconda-ks.cfg
drwx------ 3 root root 1024 Oct 24 15:04 Desktop
-rw-r--r-- 1 root root 545 Jan 19 15:22 genhtml.sh
-rw-r--r-- 1 root root 47583 Oct 24 15:01 install.log
-rw-r--r-- 1 root root 4702 Oct 24 15:01 install.log.syslog
-rwxr-xr-x 1 root root 248 Jan 19 15:56 lss.sh
-rw-r--r-- 1 root root 2737 Jan 6 12:45 main.cf.new
-rw-r--r-- 1 root root 3125 Jan 6 12:45 master.cf.new
-rwxr-xr-x 1 root root 263 Dec 5 17:39 userandgroupadd.sh

shell if语句

if语句

if语句用于条件控制,语法结构为:

if 测试条件1
then
 命令组1
[elif 测试条件2]
then
 命令组2
[else
 命令x]
fi
if,then,elif,else,fi是关键字,elif语句可以有任意多个,命令组只有在相应的测试条件成立时才执行,命令else语句中的命令x只有在所有的测试条件都不满足时才执行。then和if可以写在一行,用分号隔开:

if 测试条件1; then
 命令组1
[elif 测试条件2]; then
 命令组2]
[else
 命令x]
fi
if语句唯一可以测试的内容是命令退出状态,也就是说,测试条件是一个或多条命令,多条命令可由分号、换行符号或由逻辑操作符号连接。如果测试条件是多条命令的话,则以最后一条得到执行的命令的推出状态为准。

例子,if.sh脚本文件:
 

#!/bin/bash
echo 'type in the user name:'
 read user

if grep $user /etc/passwd > /tmp/null && who | grep $user
 # 测试条件是由&&连接的2个命令

 # grep $user /etc/passwd > /tmp/null ,从/etc/passed文件中寻找$user字段,并重定向输出到文件/tmp/null

 # who | grep $user ,who命令列出当前系统已经登录的用户,管道|链接,从其中寻找是否有$user字符串
then
 echo "$user has logged in the system."
 cp /tmp/null ~/me.tmp
 rm /tmp/null
else
 echo "$user has not logged in the system."
fi

测试:
 

[singlepig]@[~/workspace/shell-learn]$ bash if.sh
type in the user name:
singlepig
singlepig tty7  2014-01-13 08:07 (:0)
singlepig pts/3 2014-01-13 13:41 (:0.0)
singlepig has logged in the system.
[singlepig]@[~/workspace/shell-learn]$ bash if.sh
type in the user name:
pig
singlepig tty7  2014-01-13 08:07 (:0)
singlepig pts/3 2014-01-13 13:41 (:0.0)
pig has logged in the system.
[singlepig]@[~/workspace/shell-learn]$ bash if.sh
type in the user name:
fuckyou
fuckyou has not logged in the system.
 

从第二次运行程序来看,输入的用户名为pig,但是实际登录的用户是singlepig,程序输出pig已经登录。
这是有问题的,通常的理解是输入的用户名是pig,那就应该看pig这个用户是否登录,而不是看singlepig还是doublepig登录了没有。

原因在于grep语句,程序中的grep查找时会在一个字符串中查找子串。
因此,当grep pig时,所有含有pig子串的行都会被匹配出来。为了修改这个问题,可以使用正则表达式进行匹配。