首页 > 代码库 > Linux Shell脚本编写——使用结构化命令(二)

Linux Shell脚本编写——使用结构化命令(二)

结构化命令中,最基本的类型就是if-then语句
if command
then
  command
fi
bash shell的if语句会执行if行定义的那个命令,如果命令的退出状态码是0,则代表成功执行,位于then部分的命令就会执行。如果if行定义的命令的退出状态码是其他,则then部分的命令将不会执行,且if-then语句不能测试跟命令的退出状态码无关的条件
代码2-1
root@lejian:/data# cat demo1 
#!/bin/bash
if date
then
        echo "hello world"
fi
root@lejian:/data# ./demo1 
Fri Dec  2 05:26:27 CST 2016
hello world

  

如果故意放置一个不能执行的命令,则不会进入then
代码2-2
root@lejian:/data# cat demo2 
#!/bin/bash
if aaa
then
        echo "hello world"
fi
root@lejian:/data# ./demo2 
./demo2: line 2: aaa: command not found

  

if-then-else
代码2-3
root@lejian:/data# cat demo3 
#!/bin/bash
if aaa
then
        echo "hello world"
else
        echo "hello java"
fi
root@lejian:/data# ./demo3 
./demo3: line 2: aaa: command not found
hello java

  

 
嵌套if,else可有可无,如果所有条件都不符合,则进入else
if command1
then
command set 1
elif command2
then
command set 2
elif command3
then
command set 3
else
command set 4
fi
 
代码 
 2-4
root@lejian:/data# cat demo4 
#!/bin/bash
if aaa
then
        echo "hello world"
elif who
then
        echo "hello java"
else
        echo "hello linux"
fi
root@lejian:/data# ./demo4 
./demo4: line 2: aaa: command not found
root     pts/0        2016-12-02 04:39 (122.91.222.126)
hello java

  

 
test命令可以判断3类条件(注:[ condition ]condition两边必须加空格):
  • 数值比较
  • 字符串比较
  • 文件比较
if test condition
then
commands
fi
if[ condition ]
then
commands
fi
 
数字比较
比较 描述
n1 -eq n2 检查n1是否与n2相等
n1 -ge n2 检查n1是否大于等于n2
n1 -gt n2 检查n1是否大于n2
n1 -le n2 检查n1是否小于等于n2
n1 -lt n2 检查n1是否小于n2
n1 -ne n2 检查n1是否不等于n2
 
 代码2-5
root@lejian:/data# cat demo3 
#!/bin/bash
val1=10
val2=20
if [ $val1 -gt $val2 ]
then
        echo "The test value $val1 is greater than $val2 "
elif [ $val1 -lt $val2 ]
then
        echo "The test value $val1 is less than $val2"
else
        echo "The test value $val1 is equal $val2  "
fi
root@lejian:/data# ./demo3 
The test value 10 is less than 20

  

 
字符串比较
比较 描述
str1 = str2 检查str1是否和str2相同
str1 != str2 检查str1是否和str2不同
str1 > str2 str1是否比str2大
str1 < str2 str1是否比str2小
-n str1 检查str1的长度是否非0
-z str2 检查str1的长度是否为0
代码2-6
root@lejian:/data# cat demo4 
#!/bin/bash
testUser=$USER
badUser=Tom
if [ $USER = $testUser ]
then
        echo "hello $USER"
fi

if [ $USER = $badUser ]
then
        echo "hello $USER"
else
        echo "User is $USER"
fi
root@lejian:/data# ./demo4 
hello root
User is root

  

 
字符串顺序
 
要测试一个字符串是否比另一个字符串大就变得繁琐了:
  • 大于小于符号必须转义,否则shell会把它们当做重定向符号而把字符串值当做文件名
  • 大于小于顺序和sort命令所采用的不同
 代码2-7
root@lejian:/data# cat demo5 
#!/bin/bash
val1="hello"
val2="Hello"
if [ $val1 \> $val2 ]
then
        echo "The result is $val1 greater than $val2"
elif [ $val1 \< $val2 ]
then
        echo "The result is $val1 less than $val2"
fi
root@lejian:/data# ./demo5 
The result is hello greater than Hello

root@lejian:/data# cat demo6 
#!/bin/bash
val1="hello"
val2="world"
if [ $val1 \> $val2 ]
then
        echo "The result is $val1 greater than $val2"
elif [ $val1 \< $val2 ]
then
        echo "The result is $val1 less than $val2"
fi
root@lejian:/data# ./demo6 
The result is hello less than world

  

 
sort和test处理字符串相反,sort默认升序,sort中大写字母大于小写字母,而test中则是小写字母大于大写字母
代码2-8
root@lejian:/data# cat demo7 
Hello 
hello
root@lejian:/data# sort demo7 
hello
Hello 

  

 
字符串大小
root@lejian:/data# cat demo8 
#!/bin/bash
val1="testing"
val2=""
if [ -n $val1 ]
then
        echo "The string ‘$val1‘ is not empty"
else
        echo "The string ‘$val1‘ is empty "
fi

if [ -n $val2 ]
then
        echo "The string ‘$val2‘ is not empty"
else
        echo "The string ‘$val2‘ is empty "
fi

if [ -n $val3 ]
then
        echo "The string ‘$val3‘ is not empty"
else
        echo "The string ‘$val3‘ is empty "
fi
root@lejian:/data# ./demo8 
The string ‘testing‘ is not empty
The string ‘‘ is not empty
The string ‘‘ is not empty

代码2-8中:

if [ -n $val1 ]判断val1变量长度是否为0,而它长度正好非0,所以then部分被执行了
if [ -z $val2 ]判断val2变量长度是否为0,而它正好长度为0,所以then部分被执行了
if [ -z $val3 ]判断val3变量长度是否为0,这个变量并未在shell脚本中定义过,所以说明字符串长度仍未0,所以then部分执行
 
 
文件比较
比较 描述
-d file 检查file是否存在并是个目录
-e file 检查file是否存在
-f file 检查file是否存在并是个文件
-r file 检查file是否存在并可读
-s file 检查file是否存在并非空
-w file 检查file是否存在并可写
-x file 检查file是否存在并可执行
-O file 检查file是否存在并属当前用户所拥有
-G file 检查file是否存在并且默认组与当前用户相同
file1 -nt file2 检查file1是否比file2新
file1 -ot file2 检查file1是否比file2旧
 
检查目录
 代码2-8
root@lejian:/data# cat demo9 
#/bin/bash
if [ -d $HOME ]
then
        echo "Your home directory exists"
        cd $HOME
        ls -a
else
        echo "There is a problem with your HOME directory"
fi
root@lejian:/data# ./demo9 
Your home directory exists
.  ..  .bash_history  .bashrc  .cache  .hivehistory  .pip  .profile  .pydistutils.cfg  .rediscli_history  .scala_history  .selected_editor  .spark_history  .ssh  .vim  .viminfo

  

检查文件是否为空
代码2-9
root@lejian:/data# cat demo1 
#!/bin/bash
file="text"
touch $file
if [ -s $file ]
then
        echo "The $file file exists and has data in it"
else
        echo "The $file exists and is empty"
fi
date > $file
if [ -s $file ]
then
        echo "The $file file exists and has data in it"
else
        echo "The $file exists and is empty"
fi
root@lejian:/data# ./demo1 
The text exists and is empty
The text file exists and has data in it

  

 
 
使用布尔逻辑来组合测试:
  • [ condition1 ] && [ condition2 ]
  • [ condition1 ] || [ condition2 ]
 代码2-10
 
root@lejian:/data# cat demo2 
#!/bin/bash
if [ -d $HOME ] && [ -w $HOME/testing ]
then
        echo "The file exists and you can write it"
else
        echo "I cannot write to the file"
fi
root@lejian:/data# ./demo2 
I cannot write to the file

  

 
使用双圆括号将高级数学表达式放入比较中((expression))
符号 描述
val++ 后增
val-- 后减
++val 先增
--val 先减
! 逻辑求反
- 位求反
** 幂运算
<< 位左移
>> 位右移
& 位布尔和
| 位布尔或
&& 逻辑和
|| 逻辑或
 代码2-11
root@lejian:/data# cat demo3 
#!/bin/bash
val1=10
if(($val1 ** 2 > 90))
then
        ((val2=$val1 ** 2))
        echo "The square of $val1 is $val2"
fi
root@lejian:/data# ./demo3 
The square of 10 is 100

  

 
使用双方括号
 
[[expression]]提供了test命令未提供的另一特性——模式匹配
 代码2-12
root@lejian:/data# cat demo4 
#!/bin/bash
if [[ $USER=r* ]]
then
        echo "hello $USER"
else
        echo "Sorry. I do not know you"
fi
root@lejian:/data# ./demo4 
hello root

  

 
case命令会检查单个变量列表格式的多个值,符号“;;”类似C语言中的break,但是又与C语言有点不太一样,C语言允许没有break,一直到匹配结束,而shell脚本中的case匹配如果没有";;"这个符号则会报错
 
case variable in
pattern1 | pattern2) command1;;
pattern3) command2;;
*) default commands;;
 
代码2-13
root@lejian:/data# cat demo5 
#!/bin/bash
case $USER in
root|Tom)
        echo "Welcome $USER"
        echo "Please enjoy your visit";;
testing)
        echo "Special testing account";;
jessica)
        echo "Do not forget to log off when you‘re done";;
*)
        echo "Sorry. you are not allowed here";;
esac
root@lejian:/data# ./demo5 
Welcome root
Please enjoy your visit

  

Linux Shell脚本编写——使用结构化命令(二)