前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Linux命令行与shell脚本编程大全》第十二章 使用结构化命令

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

作者头像
xcywt
发布2018-01-11 17:29:18
8680
发布2018-01-11 17:29:18
举报
文章被收录于专栏:xcywtxcywt

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

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

12.1 使用if-then语句

如下格式:

代码语言:js
复制
if command
then
         commands
fi

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

例子:

代码语言:js
复制
 #!/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会把这些命令当成一个块,要么不执行,要么全部执行。

例子:

代码语言:js
复制
 #!/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语句

另外一组命令:

代码语言:js
复制
if command
then
         commands
else
         commands
fi

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

例子:

代码语言:js
复制
 #!/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

可以这样

代码语言:js
复制
if command
then
 if commands
         then
                   commands
         else
                   commands
         fi
else
         commands
fi

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

代码语言:js
复制
if command1
then
         command1s
elif command2
then
command2s
elif command3
then
command3s
else
         commands
fi

例子:

代码语言:js
复制
 #!/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语句就不会再被执行了

格式如下:

代码语言:js
复制
if test condition
then
         commands
fi

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

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

还可以这么写:

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

代码语言:js
复制
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命令恰好

例子:

代码语言:js
复制
 #!/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旧

例子:

代码语言:js
复制
 #!/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命令未提供的另一个特性 – 模式匹配

例子:

代码语言:js
复制
 #!/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命令会采用列表格式来检查单个变量的多个值。

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

代码语言:js
复制
case variable in
pattern1 | pattern2 ) commands1;;
pattern3) commands2;;
*) default commands;;
esac

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

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

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

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

例子:

代码语言:js
复制
 #!/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
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-11-21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 12.1 使用if-then语句
  • 12.2 if –then-else语句
  • 12.3嵌套if
  • 12.4 test命令
    • 12.4.1 数值比较
      • 12.4.2 字符串比较
        • 12.4.3 文件比较
        • 12.5 符合条件测试
        • 12.6 if-then的高级特性
          • 12.6.1 使用双括号
            • 12.6.2 使用双方括号
            • 12.7 case命令
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档