《Linux命令行与shell脚本编程大全》第十二章 使用结构化命令

许多程序要就对shell脚本中的命令施加一些逻辑控制流程。

结构化命令允许你改变程序执行的顺序。不一定是依次进行的

12.1 使用if-then语句

如下格式:

if command
then
         commands
fi

if语句会允许if后面的那个命令,如果该命令的退出码的0(代表成功了)位于then部分的命令就会被执行。否则不执行。

例子:

 #!/bin/bash
 # if then test
 if pwd  
 then
 echo “pwd success”
 fi
 # this is error cmd, no run then commands
 if thisErrorCmd 
 then
 echo “Com success”
 fi
 echo “this end”

then部分可以使用不止一条命令。bash  shell会把这些命令当成一个块,要么不执行,要么全部执行。

例子:

 #!/bin/bash
 # if then test
 testuser=xcy
 if grep $testuser /etc/passwd
 then
 echo "this is first command"
 echo "this is second command"
 echo "i can even put in other commands besides echo:"
 ls -a /home/$testuser/.b*
 fi 

12.2 if –then-else语句

另外一组命令:

if command
then
         commands
else
         commands
fi

else 后面也可以接多条命令。

例子:

 #!/bin/bash
 # if then test
 testuser=hshsh
 if grep $testuser /etc/passwd
 then
 echo "this is first command"
 echo "i can even put in other commands besides echo:"
 ls -a /home/$testuser/.b*
 else
 echo "error: this is first command"
 echo "error: not find user $testuser"
 fi 

12.3嵌套if

可以这样

if command
then
 if commands
         then
                   commands
         else
                   commands
         fi
else
         commands
fi

这种嵌套问题在于代码不易阅读,很难理清楚逻辑流程。下面介绍另外一种方式:

if command1
then
         command1s
elif command2
then
command2s
elif command3
then
command3s
else
         commands
fi

例子:

 #!/bin/bash
 # if-then-elif  test, can changed testuser testuser1
 testuser=xcy
 testuser1=xcy
 if grep $testuser /etc/passwd
 then
         echo "step0:i can even put in other commands besides echo:"
         ls -a /home/$testuser/.b*
 elif grep $testuser1 /etc/passwd
 then
         echo "step1: i can even put in other commands besides echo:"
         ls -a /home/$testuser1/.b*
 else
         echo "not find user $testuser and $testuser1"
 fi

12.4 test命令

test提供了在if-then语句中测试不同条件的的途径。

如果test命令中列出的条件成立,test命令就就会退出并返回退出状态码0。这样if then就会顺利执行了。

如果不成立,test命令就会退出并返回非0的退出状态码。if-then语句就不会再被执行了

格式如下:

if test condition
then
         commands
fi

当你假如一个条件时,test会测试该条件。

(1)如果不写condition部分,会以非0的退出状态码退出。

还可以这么写:

// 注意condition两边一定要有空格。

if [ condition ]
then
         commands
fi

test 可以判断三类条件:

数值比较

字符串比较

文件比较

12.4.1 数值比较

下面是数值比较命令的表:不能在test命令中使用浮点数

n1 –eq n2  相当于 ==

n1 –ge n2  相当于 >=

n1 –gt n2  相当于 >

n1 –le n2  相当于 <=

n1 –lt n2  相当于 <

n1 –ne n2  相当于 !=

12.4.2 字符串比较

str1 = str2  是否相同

str1 != str2  是否不相同

str1 < str2  str1是否小于str2

str1 > str2  str1是否大于str2

-n  str1  长度是否非0

-z  str1  长度是否为0

1. 字符串相等性

直接用=,  != 就行了

2. 字符串顺序:有两个注意事项

(1)大于号小于号必须转义,否则会被认为是重定向

(2)大于和小于顺序 和 sort采用的不同。

比较测试中大写字母是小于小写字母的。sort命令恰好

例子:

 #!/bin/bash
 # test command test
 if test
 then
         echo "step1 true"
 else
         echo "step1 false"
 fi
  
 num=8
 if [ $num -ge 8 ]  # 还可以接 –le  -eq 等一大堆
 then
         echo "step2 num >= 8"
 else
         echo "step2 num not >= 8"
 fi
  
 testuser=xcddy
 if [ $USER != $testuser ]
 # if [ $USER = $testuser ]
 then
         echo "step3, user not $testuser"
 else
         echo "step3, user is $testuser"
 fi
  
 str1=Test1  # small
 str2=test1  # big
 if [ $str1 \> $str2 ]  #  需要转义
 then
         echo "step4, $str1 > $str2"
 else
         echo "step4, $str1 <= $str2"
 fi
  
 str3=
 if [ -z $str3 ]
 #if [ -n $str3 ]
 then
         echo "step5, $str3 len is 0"
 else
         echo "step5, $str3 len is not  0"
 fi

12.4.3 文件比较

最为强大,也是用的最多的比较形式。允许测试liunx文件系统上文件和目录的状态

-d file  是否存在并且是目录

-e file  是否存在

-f file  是否存在并且是文件

-r file  是否存在并可读

-s file  是否存在并非空

-w file  是否存在并可写

-x file  是否存在并可执行

-O file  是否存在并属当前用户所有  // 大写的O

-G file  是否存在并默认组与当前用户相同

file1 –nt file2  file1是否比file2新

file1 –ot file2  file1是否比file2旧

例子:

 #!/bin/bash
 jump_dir=testDir
 if [ -d $jump_dir ]
 then
         echo "$jump_dir is exist, now change in this:"
         cd $jump_dir
         echo -n  "now pwd:" 
         pwd
 else
         echo "$jump_dir is not exist, should create Dir"
         mkdir $jump_dir
         echo "change Dir to $jump_dir"
         cd $jump_dir
         echo -n  "now pwd:" 
         pwd
 fi
  
 test_file=moduleok
 if [ -e $test_file ]
 then
         echo "$test_file is exist" 
         mv moduleok running
         sleep 3
         mv running moduleok
 else
         echo "$test_file is not exist, touch this:" 
         touch $test_file
         mv moduleok running
         sleep 3
         mv running moduleok
 fi
  
 echo "check up dir:"
 cd ..
 echo -n  "now pwd:" 
 pwd
  
 run_test=test2
 if [ -x $run_test ]
 then
         echo "you can run the script: $run_test"
         ./$run_test
 else
         echo "you are unable to execute the script: $run_test"
 fi
  
 file1=test1
 file2=test5
 if [ $file1 -nt $file2 ]
 then
         echo "$file1 is new, $file2 is old"
 else
         echo "$file1 is old, $file2 is new"
 fi

12.5 符合条件测试

if-then 允许使用布尔逻辑来组合测试:

(1)[ condition1 ] && [ condition2 ]:使用AND布尔运算符来组合两个条件

(2)[ condition1 ] || [ condition2 ]:使用OR来组合两个条件

12.6 if-then的高级特性

提供了两项可在if-then语句中使用的高级特性:

(1)用于数学表达式的双括号

(2)用于高级字符串处理功能的双方括号

12.6.1 使用双括号

test命令只能在比较中使用简单的算数操作。

允许你在比较过程中使用高级数学表达式。提供了更多的数学符号

val++, val--  后增  后减

++val, --val   先增  先减

! 逻辑求反

~ 位求反

**  幂运算

<<  左位移  >>  右位移

& 位布尔和   |  位布尔或

&& 逻辑和  ||  逻辑或

双括号里面的大于号不需要转义

12.6.2 使用双方括号

注意不是所有的shell都支持双方括号。

在模式匹配中可以定义一个正则表达式来匹配字符串

[[ expression ]]

expression使用了test命令中采用的标准字符串比较,但它提供了test命令未提供的另一个特性 – 模式匹配

例子:

 #!/bin/bash
 # (( )) test
 val=10
 #val=5
 if (( val ** 2 > 90 ))
 then
         echo "$val ^ 2 > 90"
         (( val2 = $val ** 2 ))
         echo "Result: $val ^ 2 is $val2"
 else
         echo "$val ^ 2 < 90"
 fi
  
 str1=xcyhaha
 if [[ $str1 == xcy* ]]
 then
         echo "str1 == xcy* , str1 is $str1"
 else
         echo "str1 != xcy* , str1 is $str1"
 fi

12.7 case命令

有了case命令就不需要再写出所有的elif语句来不停的检查同一个变量的值了。

case命令会采用列表格式来检查单个变量的多个值。

语法:注意后面的那两个分号

case variable in
pattern1 | pattern2 ) commands1;;
pattern3) commands2;;
*) default commands;;
esac

case命令会将指定的变量与不同模式进行比较。如果变量和模式匹配,那么shell会执行为改模式指定的命令。

可以通过竖线操作符在一行中分割出多个模式模式。

*星号会捕获所有与已知模式不匹配的值。

case命令提供了一个更清晰的方法来为变量每个可能的值指定不同的选项。

例子:

 #!/bin/bash
 var=68
 case $var in
 3)
         echo "var == 3";;
 4)
         echo "var == 4";;
 5)
         echo "var == 5";;
 7|6)
         echo "var == 6|7";;
 *)
         echo "var defaule";;
 esac

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏天天

onload事件

27020
来自专栏C/C++基础

C++名字空间详解

名字空间(namespace)是由标准C++引入的,是一种新的作用域级别。原来C++标识符的作用域分为三级:代码块({…}和函数体)、类域和全局作用域。如今,在...

7210
来自专栏木木玲

“类加载机制”详解

38010
来自专栏漫漫深度学习路

tensorflow错误总结

在写tensorflow代码的时候,经常会出现一些错误,在此记录一下,希望不要采同样的坑。 错误总结 bias = tf.get_variable("bias"...

19390
来自专栏JavaEdge

类加载的过程1 加载2 验证3 准备4 解析5 初始化

330120
来自专栏黑泽君的专栏

Java中,成员内部类的常见修饰符及应用 && 成员内部类不是静态的,访问的格式

成员内部类的常见修饰符及应用:   private    为了保证数据的安全性   static      为了方便访问数据   注意:静态的内...

12020
来自专栏C/C++基础

C++中cin的详细用法

cin是C++编程语言中的标准输入流对象,即istream类的对象。cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout是流的对象...

40930
来自专栏xingoo, 一个梦想做发明家的程序员

Ruby对象模型总结

参考《Ruby元编程》,元编程,即 用来编写代码的代码 。 对象由一组实例变量和一个类的引用组成 对象的方法存在与对象所属的类中,类似js中的protot...

24080
来自专栏Golang语言社区

Golang语言--包的概念、导入与可见性

go中包的概念、导入与可见性 ? 包是结构化代码的一种方式:每个程序都由包(通常简称为 pkg)的概念组成,可以使用自身的包或者从其它包中导入内容。 如同其它一...

42850
来自专栏我和PYTHON有个约会

16.pass关键字

在项目开发的过程中,某些情况下,我们定义了函数,但是对于函数中具体的代码临时没有确定,如:

11130

扫码关注云+社区

领取腾讯云代金券