许多程序要就对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

《Linux命令行与shell脚本编程大全》第十二章 使用结构化命令的更多相关文章

  1. 《Linux命令行与shell脚本编程大全》 第二十七章 学习笔记

    第二十七章:shell脚本编程进阶 监测系统统计数据 系统快照报告 1.运行时间 uptime命令会提供以下基本信息: 当前时间 系统运行的天数,小时数,分钟数 当前登录到系统的用户数 1分钟,5分钟 ...

  2. 《Linux命令行与shell脚本编程大全》 第二十三章 学习笔记

    第二十三章:使用数据库 MySQL数据库 MySQL客户端界面 mysql命令行参数 参数 描述 -A 禁用自动重新生成哈希表 -b 禁用 出错后的beep声 -B 不使用历史文件 -C 压缩客户端和 ...

  3. 《Linux命令行与shell脚本编程大全》 第六章环境变量

    很多程序和脚本都通过环境变量来获取系统信息.存储临时数据和配置信息. 6.1 什么是环境变量: bash shell用一个叫环境变量(environment variable)的特性来存储有关shel ...

  4. 《Linux命令行与shell脚本编程大全》第十三章 更多的结构化命令

    本章讨论bash shell的循环命令for.while和until 13.1 for命令 重复执行一系列命令在编程中很常见. bash shell提供了for命令,允许你创建一个遍历一系列值的循环. ...

  5. 《Linux命令行与shell脚本编程大全》第二十一章 sed进阶

    本章介绍一些sed编辑器提供的高级特性. 21.1 多行命令 按照之前的知识,所有的sed编辑器命令都是针对单行数据执行操作的. 在sed编辑器读取数据流时,它会基于换行符的位置将数据分成行,一次处理 ...

  6. 《Linux命令行与shell脚本编程大全》第十一章 构建基本脚本

    11.1使用多个命令 $date;who   //  命令列表,加入分号就可以,这样会依次执行.参见5.2.1节 注意区分$(date;who),这个是进程列表,会生成一个子shell来执行 Shel ...

  7. 《Linux命令行与shell脚本编程大全》 第三章 学习笔记

    第三章:基本的bash shell命令 bash程序使用命令行参数来修改所启动shell的类型 参数 描述 -c string 从string中读取命令并处理他们 -r 启动限制性shell,限制用户 ...

  8. 《Linux命令行与shell脚本编程大全》第十七章 创建函数

    可以将shell脚本代码放进函数中封装起来,这样就能在脚本中的任何地方多次使用它了. 17.1 基本的脚本函数 函数:是一个脚本代码块,可以为其命名并在代码中任何位置重用. 17.1.1 创建函数 有 ...

  9. 《Linux命令行与shell脚本编程大全》 第五章理解shell

    5.1 1. cat /etc/passwd 可以查看每个用户自己的默认的shell程序. 2.默认的交互shell会在用户登录某个虚拟控制台终端时启动. 不过还有另外一个默认的shell是/bin/ ...

  10. 《Linux命令行与shell脚本编程大全》 第七章理解Linux文件权限

    Linux沿用了Unix文件权限的方法,允许用户和组根据每个文件和目录的安全性设置来访问文件. 用户权限通过创建用户时分配的用户ID(UID)来跟踪的.每个用户有唯一的ID,但是登录时用的不是UID, ...

随机推荐

  1. Python和SQL Server 2017的强大功能

    Python和SQL Server 2017的强大功能 摘要: 源:https://www.red-gate.com/simple-talk/sql/sql-development/power-pyt ...

  2. Android架构: MVC 新浪微博

    由于项目的需要,最近研究了一下需要连接网络项目的MVC架构,参考了一下一个新浪微博的开发架构 http://www.open-open.com/lib/view/open1345524526767.h ...

  3. IDEA搭建SpringMVC+Mybatis+Mysql+Maven框架

    相关环境 Intellij IDEA Ultimate Tomcat JDK MySql 5.6(win32/win64) Maven (可使用Intellij IDEA自带的) 搭建步骤 创建项目工 ...

  4. OOAD-设计模式(二)之GRASP模式与GOF设计模式概述

    一.GRASP模式(通用责任分配软件模式)概述 1.1.理解责任 1)什么是责任 责任是类间的一种合约或义务,也可以理解成一个业务功能,包括行为.数据.对象的创建等 知道责任——表示知道什么 行为责任 ...

  5. LeetCode 122. Best Time to Buy and Sell Stock II (买卖股票的最好时机之二)

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  6. 【Vue】利用父子组件间通信实现一个场景

    组件间通信是组件开发的,我们既希望组件的独立性,数据能互不干扰,又不可避免组件间会有联系和交互. 在vue中,父子组件的关系可以总结为props down,events up: 在vue2.0中废弃了 ...

  7. H5新特性汇总

    H5新特性: 新增选择器 document.querySelector.document.querySelectorAll 拖拽释放(Drag and drop) API 媒体播放的 video 和 ...

  8. 用C写的计算运行时间

    #include <stdio.h> #include <stdlib.h> #include <time.h> int main( void ) { long i ...

  9. Java中的类变量、实例变量、类方法、实例方法的区别

    类变量:形如static int a; 顾名思义,类变量可以理解为类的变量,类变量在类加载的时候就已经给它分配了内存空间,不同于实例变量(int a; ),实例变量是在该类创建对象的时候分配内存的.并 ...

  10. 原生JS实现Ajax及Ajax的跨域请求

      前  言          如今,从事前端方面的程序猿们,如果,不懂一些前后台的数据交互方面的知识的话,估计都不太好意思说自己是程序猿.当然,如今有着许多的框架,都有相对应的前后台数据交互的方法. ...