shell--使用结构化命令

使用结构化命令
知识内容:
# 改变命令流
# 使用if-then逻辑
# 嵌套if-then
# 测试条件
# 高级if-then功能
许多程序在脚本命令之间需要某些逻辑控制流,有些命令允许脚本根据变量值的条件或者命令的结果跳过一些命令或者循环

执行这些命令,这叫做结构化命令。
1、使用if-then语句
最基本的结构化命令类型就是if-then语句,其格式如下:
if command
then

command
fi
意思是说:if语句后面的命令的退出状态值是0,则执行then后面的所有命令;如果不是0则命令不执行。如下例子:
[root@wzp ~]# cat test2
#!/bin/bash
if date
then
        echo "it works"
fi
[root@wzp ~]# ./test2
2011年 01月 28日 星期五 21:15:12 CST
it works
我们知道date命令是有效命令,查看$?肯定是0的,所以就执行then后的命令,这个应该不难理解。
2、if-then-else语句
这个语句可以提供一组命令,其格式如下:
if command
then
        command
else
        command
if
意思是说:if语句后面的命令的退出状态值是0,则执行then后面的所有命令;跟if-then一样,如果不是则执行else后面的

命令。如下例子:
[root@wzp ~]# cat test2
#!/bin/bash
testuser=51cto
if grep $testuser /etc/passwd
then
        echo  the files for $testuser are:
        ls -a /home/$testuser/.*
else
        echo the user name $testuser does not exist !
fi
[root@wzp ~]# ./test2
the user name 51cto does not exist !
从上面可以看到由于不存在51cto用户,则执行else后面的命令
但是当我创建了51cto用户,则:
[root@wzp ~]# useradd 51cto
[root@wzp ~]# ./test2
51cto:x:502:502::/home/51cto:/bin/bash
the files for 51cto are:
/home/51cto/.bash_logout   /home/51cto/.bashrc
/home/51cto/.bash_profile  /home/51cto/.emacs

/home/51cto/.:
.  ..  .bash_logout  .bash_profile  .bashrc  .emacs  .mozilla

/home/51cto/..:
.  ..  51cto  aa  bb  lost+found

/home/51cto/.mozilla:
.  ..  extensions  plugins
直接执行then后的命令!这个也容易理解!~
3、嵌套if语句
有时需要在脚本代码中检查几种情况,可以使用else的另一种版本叫elif,但是要嵌套许多if-then语句,后续有case命令介

绍,这个更加的方便使用,这里就不对嵌套if语句详解了,其格式是:
if command
then
        command
elif    command
then
   
command
fi
4、test命令
这是一个重头戏,bash shell提供一种在if-then语句中声明test命令的另一种方法:
if [ condition ]  //注意这里的condition两边有空格!切记!
then
        command
fi
test命令能够评估以下3类命令:
# 数值比较
# 字符串比较
# 文件比较
下面就具体就test命令的用户逐一说明!!!
4.1、数值比较
如下式数值比较表:
**********************************************
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
**********************************************
下面看看一个例子:
[root@wzp ~]# cat test2
#!/bin/bash
num1=10
num2=11
if [ $num1 -gt 5 ]
then
  echo the test value $num1 is greater than 5
fi

if [ $num2 -eq $num1 ]
then
  echo  the values are equal
else
  echo  the values are different
fi
[root@wzp ~]# ./test2
the test value 10 is greater than 5
the values are different
给num1和num2赋值,然后通过测试,得出不同结论,这个好理解!
4.2、字符串比较
test命令允许对字符串值进行比较,主要分为如下三种比较类型:
1、字符串是否相同
2、字符串顺序(大小)
3、字符串长度
首先也先看看test命令字符串比较表
********************************************
str1 = str2   检查str1和str2是否相同
str1 != str2  检查str1和str2是否不同
str1 < str2   检查str1是否小于str2
str1 > str2   检查str1是否大于str2
  -n str1     检查str1长度是否大于0
  -z str1     检查str1长度是否为0
********************************************
下面对三种类型举个例子:
1)字符串是否相等
[root@wzp ~]# cat test2
#!/bin/bash
testuser=root
if [ $USER = $testuser ]
then
  echo welcome $testuser
fi
[root@wzp ~]# ./test2
welcome root
可以看到字符串相等的显示效果
[root@wzp ~]# cat test2
#!/bin/bash
testuser=root
if [ $USER != $testuser ]
then
  echo this is not $testuser
else
  echo welcome $testuser
fi
[root@wzp ~]# ./test2
welcome root
不相等的情况则显示else后的内容
2)字符串顺序
[root@wzp ~]# cat test2
#!/bin/bash
str1=aaa
str2=bbb
if [ $str1 > $str2 ]
then
  echo $str1 is greater than $str2
else
  echo $str1 is less than $str2
fi
[root@wzp ~]# ./test2
aaa is greater than bbb
[root@wzp ~]# ll aaa
-rw-r--r-- 1 root root 0 01-28 22:22 aaa
在脚本中单独使用了大于号>,虽然没报错,但结果是错误的,a打头肯定是小于b的。这个脚本把大于号理解成输出重定向,

所以才出现这样的情况,我们可以通过转义大于号解决这个问题:
[root@wzp ~]# cat test2
#!/bin/bash
str1=aaa
str2=bbb
if [ $str1 \> $str2 ]     //此处添加一个\就行了
then
  echo $str1 is greater than $str2
else
  echo $str1 is less than $str2
fi
[root@wzp ~]# ./test2
aaa is less than bbb
这样就得出了正确的结果!
还有一点要说明的就是大小写的问题,它的顺序跟sort命令的顺序是相反的!test命令是通过ASCII数值来决定排列顺序的,

这个稍微了解下就好。
3)字符串大小
评估一个变量是否包含数据,通过使用-n和-z比较很方便,如下例子:
[root@wzp ~]# cat test2
#!/bin/bash
str1=aaa
str2=
if [ -n $str1 ]    //长度是否大于0
then
        echo the string $str1 is not empty
else
        echo the string $str1 is empty
fi
if [ -z $str2 ]     //长度是否为0
then
        echo the string $str2 is empty
else
        echo the string $str2 is not empty
fi
if [ -z $str3 ]     //长度是否为0
then
        echo the string $str3 is empty
else
        echo the string $str3 is not empty
fi
[root@wzp ~]# ./test2
the string aaa is not empty
the string is empty
the string is empty
如上对于str1和str2应该没什么问题,而对于没有定义变量str3则认定其字符串为零。
4.3、文件比较
test命令能够检测linux文件系统上的文件状态和路径,对于文件比较这一块挺多东西的,下面一一道来,首先看看test命令

文件比较表:
****************************************************************
-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旧
*****************************************************************
对于上面这个表,如下通过10个例子说明:
1)检测目录
[root@wzp ~]# cat test2
#!/bin/bash
if [ -d $HOME ]
then
  echo your home directory exists
  cd $HOME
  ls
else
  echo there is someting wrong with your HD
fi
[root@wzp ~]# ./test2
your home directory exists
aaa              bbb      install.log         mbox  test2
anaconda-ks.cfg  Desktop  install.log.syslog  one
使用-d把我这个root的家目录ls出来了~~
2)检测对象是否存在
[root@wzp ~]# cat test2
#!/bin/bash
if [ -e $HOME ]
then
  echo   yes, the HD exists
  if [ -e $HOME/bbs.51cto ]
  then
    echo the bbs.51cto exists
  else
    touch $HOME/bbs.51cto
    echo creating new file name bbs.51cto
  fi
fi
从上面我们看到目录肯定是存在的,我的root嘛,但是这个bbs.51cto是不存在的,所以第一次执行文件显示不存在,并且私

下创建了。
[root@wzp ~]# ./test2
yes, the HD exists
creating new file name bbs.51cto
第二次执行文件那肯定是显示存在bbs.51cto了,呵呵
[root@wzp ~]# ./test2
yes, the HD exists
the bbs.51cto exists
3)检测文件
-e适合用于检测文件和目录,要确定对象是文件,使用-f比较,下例:
[root@wzp ~]# cat test2
#!/bin/bash
if [ -e $HOME ]
then
  echo the $HOME exists !
  if [ -f $HOME ]
  then
    echo yes, it is a file
  else
    echo no, it is not a file
        if [ -f $HOME/.bash_history ]
        then
          echo but $HOME/.bash_history is a file
        else
          echo it is not a file too
        fi
  fi
else
  echo there is not object!
fi
[root@wzp ~]# ./test2
the /root exists !
no, it is not a file
but /root/.bash_history is a file
上面的例子应该很好懂,注意-f是检测文件,-e可以检测文件和目录就行了!
4)检测是否可读
通过-r可检测可读性,如下例:
[51cto@wzp ~]$ whoami
51cto
[51cto@wzp ~]$ cat test
#!/bin/bash
testfile=/etc/shadow
if [ -f $testfile ]
then
  if [ -r $testfile ]
  then
    ls -l $testfile
  else
    echo "i'm unable to read the file"
  fi
else
  echo "the file doesn't exist"
fi
[51cto@wzp ~]$ sh test
i'm unable to read the file
[51cto@wzp ~]$ su - root
口令:
[root@wzp ~]# sh /home/51cto/test
-r-------- 1 root root 1204 01-28 21:27 /etc/shadow
如上可知普通用户51cto无法读取文件。
5)检测空文件
通过-s检测文件是否不为空,例子如下:
[root@wzp ~]# cat test2
#!/bin/bash
file=testfile
touch $file
if [ -s $file ]
then
  echo the file exists and has data in it
else
  echo the file exists but empty
fi
date > $file
if [ -s $file ]
then
  echo the file exists and has data in it
else
  echo the file exists but empty
fi
[root@wzp ~]# ./test2
the file exists but empty
the file exists and has data in it
先是创建空文件,然后通过重定向date进去判断文件不为空,这个好理解!
6)检测是否能够可写
通过-w检测文件是否可写,例子如下:
[root@wzp ~]# cat test2
#!/bin/bash
file=$HOME/testfile
touch $file
chmod u-w $file
now='date +%y%m%d-%H%M'
if [ -w $file ]
then
  echo the file could be written
else
  echo "the file couldn't be written"
fi
chmod u+w $file
if [ -w $file ]
then
  echo the file could be written
  $now > $HOME/testfile
  echo  and the file views $file
else
  echo "the file couldn't be written"
fi
[root@wzp ~]# ./test2
the file could be written
the file could be written
and the file views /root/testfile
[root@wzp ~]# cat /root/testfile
110129-1317
上面的例子好理解,没什么好说的。
7)检测是否能运行文件
通过-x可以检测文件是否可被执行,如下例:
[root@wzp ~]# cat test2
#!/bin/bash
file=$HOME/testfile2
touch $file
chmod u+x $file
if [ -x $file ]
then
  echo the file could be run
else
  echo "the file couldn't be run"
fi
[root@wzp ~]# ./test2
the file could be run
[root@wzp ~]# ll testfile2
-rwxr--r-- 1 root root 0 01-29 13:21 testfile2
这个也没什么疑惑之处。
8)检测所有者
通过-O可以检测你是否属于这个文件的所有者,如下例:
[root@wzp ~]# cat test2
#!/bin/bash
file=/etc/passwd
if [ -O $file ]
then
  echo "you are the owner of the $file"
else
  echo "you aren't the owner of the $file"
fi
[root@wzp ~]# ./test2
you are the owner of the /etc/passwd
[root@wzp ~]# ll /etc/passwd
-rw-r--r-- 1 root root 1877 01-28 21:27 /etc/passwd
/etc/passwd属有者肯定是root啦!
9)检测所属组
-G检测文件的默认组,如果它跟当前用户的默认组匹配,则检测成功,如下例:
[root@wzp ~]# cat test2
#!/bin/bash
file=/etc/passwd
if [ -G $file ]
then
  echo "you are in the same group as $file"
else
  echo "you aren't in the same group as the $file"
fi
[root@wzp ~]# ./test2
you are in the same group as /etc/passwd
[root@wzp ~]# ll -d /etc/passwd
-rw-r--r-- 1 root root 1877 01-28 21:27 /etc/passwd
很明显,/etc/passwd肯定属于root组咯
[root@wzp ~]# chgrp 51cto /etc/passwd
[root@wzp ~]# ll -d /etc/passwd
-rw-r--r-- 1 root 51cto 1877 01-28 21:27 /etc/passwd
[root@wzp ~]# ./test2
you aren't in the same group as the /etc/passwd
当把这个文件的所属组改成51cto后,则检测不成功了,不过现实中别做这样的修改
10)检测文件日期
一般通过-nt和-ot来比较两个文件之间的新旧,这里指的是创建或修改日期,例子:
[root@wzp ~]# ll aa bb
-rw-r--r-- 1 root root 0 01-29 13:41 aa
-rw-r--r-- 1 root root 0 01-29 14:23 bb
[root@wzp ~]# cat test2
#!/bin/bash
if [ $HOME/aa -nt $HOME/bb ]
then
  echo the aa is newer than bb
else
  echo the aa is older than bb
fi
[root@wzp ~]# ./test2
the aa is older than bb
下面我把aa文件修改下内容:
[root@wzp ~]# vim aa
[root@wzp ~]# ll aa bb
-rw-r--r-- 1 root root 3 01-29 14:28 aa
-rw-r--r-- 1 root root 0 01-29 14:23 bb
[root@wzp ~]# ./test2
the aa is newer than bb
这个结果应该很容易接受!
OKOK,到这里test命令的内容就结束了,如上各种类型比较得以说明了。
5、复合条件检测
if-then语句可以使用布尔逻辑来合并检测条件,格式:
*****************************************************
[ condition ] && [ condition ]   这个表示逻辑与 and
[ condition ] || [ condition ]   这个表示逻辑或 or
*****************************************************
如下例子:
[root@wzp ~]# cat test2
#!/bin/bash
if [ -d $HOME ] && [ -w $HOME/wzp ]
then
  echo the file exists and you can wirte $HOME/wzp
else
  echo "you can't write the file"
fi
if [ -d $HOME ] || [ -w $HOME/wzp ]
then
  echo the file exists and you can wirte $HOME/wzp
else
  echo "you can't write the file"
fi
[root@wzp ~]# ./test2
you can't write the file
the file exists and you can wirte /root/wzp
[root@wzp ~]# ll /root/wzp
ls: /root/wzp: 没有那个文件或目录
$HOME是root家目录,肯定存在的,但是不存在文件/root/wzp
6、if-then的高级特征
既然说是高级特征,必然作用非凡了,呵呵
其功能体现是通过双圆括号(())表示数学表达式和双方括号[[]]表示高级字符串处理函数。
6.1、使用双圆括号
先看一个例子:
[root@wzp ~]# cat test2
#!/bin/bash
num1=10
if (( $num1 ** 2 > 90 ))
then
  (( num2=$num1 ** 2 ))
  echo the square of $num1 is $num2
fi
[root@wzp ~]# ./test2
the square of 10 is 100
这里的**表示取幂,由此可见(())可以很方便处理数学表达式
6.2、使用双方括号
使用双方括号可以定义与字符串值相匹配的正则表达式,如例:
[root@wzp ~]# cat test2
#!/bin/bash
if [[ $USER == r* ]]
then
  echo  hello $USER
else
  echo sorry , i "don't" know you
fi
[root@wzp ~]# ./test2
hello root
[root@wzp ~]# cp test2 /home/51cto/
[root@wzp ~]# su - 51cto
[51cto@wzp ~]$ sh test2
sorry , i don't know you
这里用到了通配符*,表示r开头的任何用户,正则表达式的内容放置后面说明!
[root@wzp ~]# useradd rrr
[root@wzp ~]# cp test2 /home/rrr
[root@wzp ~]# su - rrr
[rrr@wzp ~]$ sh test2
hello rrr
这都好理解吧~~~
7、case命令
还记得前面提及到case命令吧,当在一组可能的值中寻找特定的值,可以写if-then-else语句,其中嵌套elif语句继续着if

-then检测,这样子就很冗长麻烦。所以可以通过case命令简化,以列表导向格式检测单个变量的多个值,格式为:
case xxx in
xx | xx) command;;
xx) command;;
*) default command;;
esac
下面通过一个例子:
[root@wzp ~]# cat test2
#!/bin/bash
case $USER in
root | testuser)
echo welcome $USER
echo you are admin;;
51cto)
echo welcome $USER;;
*)
echo welcome $USER;;
esac
[root@wzp ~]# ./test2
welcome root
you are admin
[root@wzp ~]# cp test2 /home/51cto/
cp:是否覆盖“/home/51cto/test2”? y
[root@wzp ~]# su - 51cto
[51cto@wzp ~]$ sh test2
welcome 51cto
判断是root和51cto用户则显示特定内容,如果通过其他用户执行,如下:
[root@wzp ~]# useradd testuser24
[root@wzp ~]# cp test2 /home/testuser24/
[root@wzp ~]# su - testuser24
[testuser24@wzp ~]$ sh test2
welcome testuser24
这个都比较好理解吧,假设通过存在的用户testuser执行,那显示的内容肯定是:
welcome testuser
your are admin
哈哈,说是admin也不正确了。

好了,对于部分结构化命令就说到这里,后续是循环、迭代等结构化命令的讲述。

转载于:https://blog.51cto.com/2942350/557914

使shell用结构化命令相关推荐

  1. Linux shell 脚本结构化命令 if-then

    shell 脚本结构化命令 1. if-then 语句基本使用 if-then 语句的基本格式: if command thencommands elifcommands elsecommands f ...

  2. linux SHELL之结构化命令

    SHELL之使用结构化命令 使用if-then语句 Bash代码   if command then commands fi 如果if后面的命令退出状态码=0,那么就执行then 另外一种形式 Bas ...

  3. Shell脚本编程基础 三 使用结构化命令

    结构化命令允许我们改变程序执行的顺序,在某些条件下执行一些命令而在其他条件下跳过另一些命令. (1)使用if-then语句 结构化命令中,最基本的类型就是if-then语句,其格式如下: if com ...

  4. shell编程(七) : [shell基础] 使用结构化命令

    接上一篇文章Linux shell编程(六): 基本shell脚本 3.2 使用结构化命令 前面介绍的都是顺序执行的命令,有时需要按照逻辑顺序执行命令,这是就需要对命令命令施加一些逻辑流程控制,这样的 ...

  5. shell脚本中的结构化命令(if-then-else、case、for、while、until) 脚本中的循环控制

    1. 结构化命令 上一次我们学习了shell脚本的一些基础知识,包括环境变量.重定向.数学运算.退出脚本的方式等,想了解的可以戳这个: shell脚本基础 之前,在我们的示例shell脚本里,shel ...

  6. Linux shell 学习笔记(8)— 使用结构化命令(if-then 语句、数值比较、字符串比较、文件比较、case 语句)

    1. 使用 if-then 语句 最基本的结构化命令就是if-then语句.if-then语句有如下格式. if command then ​ commands fi 或者 if command; t ...

  7. Linux编程 23 shell编程(结构化条件判断 命令if -then , if-then ... elif-then ...else,if test)...

    一.概述 在上一篇里讲到了shell脚本,shell按照命令在脚本中出现的顺序依次进行处理,对于顺序操作已经足够了,但许多程序要求对shell脚本中的命令加入一些逻辑流程控制,这样的命令通常叫做 结构 ...

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

    许多程序要就对shell脚本中的命令施加一些逻辑控制流程. 结构化命令允许你改变程序执行的顺序.不一定是依次进行的 12.1 使用if-then语句 如下格式: if command then     ...

  9. 学习笔记:CentOS7学习之二十二: 结构化命令case和for、while循环

    目录 学习笔记:CentOS7学习之二十二: 结构化命令case和for.while循环 22.1 流程控制语句:case 22.2 循环语句 22.1.2 for-do-done 22.3 whil ...

最新文章

  1. Visual Studio 2008 到底有多强?漫画告诉你 !
  2. Vivado IP的两种综合方式:Global 和 Out-Of-Context
  3. 为什么脚本执行一行就不动了_Centos7 批量创建用户账号脚本
  4. c语言指针写鞍点,c语言——鞍点
  5. jbpm小项目测试_尝试使用jBPM Console NG(测试版)
  6. Python语法糖——遍历列表时删除元素
  7. 20145209 2016-2017-2 《Java程序设计》第5周学习总结
  8. Extjs利用iframe无弹窗导出下载文件
  9. 定做属于自己的Lodop安装程序
  10. NYOJ----1591----模拟+map
  11. 浏览器安全检查5秒解决方案
  12. Python爬取QQ音乐评论数据
  13. Vue3 京东到家项目实战第二篇(商家详情页面及购物车完整逻辑开发) 进阶式掌握vue3完整知识体系
  14. 移动应用中的AR开发,6款最受欢迎工具推荐
  15. 解读 | 数据分析领域七大热门职业
  16. 从Hadoop到Spark、Flink,大数据处理框架十年激荡发展史
  17. Z-Libary最新地址检测,再也不用担心找不到ZLibary了
  18. 纯css3粉红猪小猪佩奇代码
  19. 共享里的文件被删除了怎么办?可尝试这三种恢复方法
  20. Xmind for mac下载与安装

热门文章

  1. Python 用pygame模块播放MP3
  2. 解决Windows下运行php Composer出现SSL报错的问题
  3. [Turn]C# 强制关闭当前程序进程(完全Kill掉不留痕迹)
  4. 悄悄地进村,打枪的不要——KyuuBackground(原 ItaBackgroundKyuu)改造完成
  5. [原创]vc中创建线程并传递参数
  6. 一步一步学Silverlight 2系列(33):Silverlight 2应用Web Service两例
  7. 身为数据科学家怎么能不掌握这四大技能!
  8. 零基础搭建Hadoop大数据处理环境
  9. 刚写的代码,就变成了遗留系统?
  10. 致歉!抖音Semi Design承认参考阿里Ant Design