Shell编程学习笔记02

第二章、判断

前言

无论什么编程语言都离不开条件判断(流控)。SHELL也不例外。

例如,用户输入的密码不够长时提示用户,你太短了

例如,用户输入了备份的目录,如果有目录继续备份,如果没有目录创建目录。

例如,用户输入成绩,如果80-100分评为优秀,如果60-79分评为合格,如果0-59分评为不合格。

Shell条件测试

数值比较 [ 整数1 操作符 整数2 ]

操作符 :

[ 20 -gt 10 ] 大于

[ 1 -It 10 ] 小于

[ 1 -eq 1 ] 等于

[ 1 -ne 10 ] 不等于

[ 20 -ge 10 ] 大于等于

[ 10 -le 10 ] 小于等于

示例:

需求:猜测用户输入的密码,是否满足长度需求

脚本:

read -p "请输入您的密码:" ps

if [ ${#ps} -It 7 ]

then

echo "您的密码过短!"

else

echo "您的密码过长!"

fi

测试:

[root@localhost ~]# bash pass1.sh

请输入您的密码:123

您的密码过短!

[root@localhost~]# bash pass1.sh

请输入您的密码:123456

您的密码过短!

[root@localhost ~# bash pass1.sh

请输入您的密码:1234567

测试 您的密码过长!

文件测试 [ 操作符 文件或目录 ]

操作符:

-f filename:当filename存在时返回真

-b filename:当filename存在并且是块文件时返回真(返回0)

-d pathname:当pathname存在并且是一个目录时返回真

-h filename:当filename存在并且是符号链接文件时返回真(或-L filename)

-c filename:当filename存在并且是字符文件时返回真

-e pathname:当由pathname指定的文件或目录存在时返回真

-g pathname:当由pathname指定的文件或目录存在并且设置了SGID位时返回真

-k pathname:当由pathname 指定的文件或目录存在并且设置了“粘滞”位时返回真

-p filename:当filename存在并且是命名管道时返回真

-r pathname:当由pathname指定的文件或目录存在并且可读时返回真

-s filename:当filename存在并且文件大小大于0时返回真

-S filename:当filename存在并且是socket 时返回真

-t fd :当fd 是与终端设备相关联的文件描述符时返回真

-w pathname:当由pathname指定的文件或目录存在并且可写时返回真

-x pathname:当由pathname指定的文件或目录存在并且可执行时返回真

-O pathname:当由pathname存在并且被当前进程的有效用户id的用户拥有时返回真(字母O 大写)

-G pathname:当由pathname存在并且属于当前进程的有效用户id的用户的用户操作符(了解) 组时返回真

字符串比较[ "字符串" = "字符串" ]

=,等于

需求:邀请用户确认,yes升级装备,no不升级装备

脚本:

read -p "您确定要升级这件装备吗?" select

if [ "$select" = "yes" ]

then echo "装备升级开始。。。"

else echo "感谢您,欢迎下次光临。"

fi

测试:

[root@localhost ~]# bash yes.sh

您确定要升级这件装备吗?yes

装备升级开始。。。

[root@localhost ~]# bash yes.sh

您确定要升级这件装备吗?no

感谢您,欢迎下次光临。

!=,不等于
注意:

-z:判断字符长度是为0(了解)

-n:判断字符长度不是为0

双引号的重要性,解决一元表达式的问题(在Shell脚本中,双引号的重要性在于保留字符串的原始形式,并防止其中的特殊字符被解释或扩展。)

例:

[root@localhost ~]# BBB=" "

[root@localhost ~]# echo $(#BBB)

0

[root@localhost ~]# [ -z "$BBB" ]

[root@localhost ~]# echo $?

0

[root@localhost ~]# [ -n "$BBB" ]

[root@localhost ~]# echo $?

1

and 和 or

简介:

当条件测试比较复杂时,需要多个条件同时成立。就需要混合条件测试了。

逻辑的(and)与(or)

&& 逻辑的AND的意思,-a,两个条件同时成立,为真。

|| 逻辑的OR的意思,-o,两个条件一个成立,为真。

多种表达方法:

[root@localhost ~]# [ 1 -It 2 -a 5 -gt 10 ]

[root@localhost ~]# [ 1 -It 2 -o 5 -gt 10]

[root@localhost ~]# [[ 1 -lt 2 && 5 -gt 10 ]]

[root@localhost ~]# [[1 -It 2 || 5 -gt 10 ]]

[root@localhost ~]# [ 1 -It 2 ] && [ 11 -gt 10 ]

流程控制:if

单分支结构

语法:

if [ command/test ] ; then

符合该条件执行的语句

fi

示例:

需求:编写脚本,由用户输入用户名,如果用户不存需求 在,则创建该用户

演示:

#!/bin/bash

read -p "请输入需创建的用户名:" name

id $name &> /dev/null

if [ $? -ne 0 ] ; then

useradd $name

echo "$name 创建成功"

fi

双分支结构

语法:

if 条件测试

then

命令序列

else

命令序列

fi

示例:

需求:编写脚本,由用户输入用户名,如果用户不存在,则创建该用户,并设置密码为公123456;否则,提示用户已经存在

演示:

#!/bin/bash

read -p "Input username: " name

if id $name &> /dev/null; then

echo "$name already exist"

else

useradd $name

echo "123456" | passwd --stdin $name &> /dev/null

echo "$name create finished,the password is123456"

fi

多分支结构

语法:

if 条件测试1

then 命令序列

elif 条件测试2

then 命令序列

elif 条件测试3

then 命令序列...

else 命令序列

fi

示例:

需求 :

6-10 this is morning

11-13 this is noon

14-18 this is afternoon

其他 this is night

演示:

#!/bin/bash

hour=`date +%H`

if [ $hour -ge 6 -a $hour -le 10 ];then

echo "This is morning"

elif [ $hour -ge 11 -a $hour -le 13 ];then

echo "This is noon"

elif [ $hour -ge 14 -a $hour -le 18 ];then

echo "This is afternoon"

else

echo "This is night"

fi

嵌套结构

语法:

嵌套结构

if 条件测试1 then 命令序列

if 条件测试1 then 命令序列

else 命令序列

fi

else 命令序列

fi

示例:

需求:输入用户名,若用户名存在(then)则提醒用户存在;若用户不存在,则创建用户并提醒用户输入密码。若输入的密码大于7位,则创建用户成功;若输入的密码小于7位,则提醒密码不符合要求

演示:

#!/bin/bash

read -p"请输入新用户名:" name

id $name &> /dev/null

if [ $? -eq 0 ]

then

echo "$name用户已经存在,不需要创建。"

else

read -p "用户即将创建,请输入新密码:" pass

if [ ${#pass} -ge 7 ]; then

useradd $name

echo "$name创建成功。"

echo $pass | passwd -- stdin $name

echo "$name用户的密码是$pass"

else

echo "您输入的新密码不足7位,创建密码失败。"

fi

fi

调试脚本

# sh -n 1.sh 仅调试脚本中的语法错误。

# sh -vx 1.sh 以调试的方式执行,查询整个执调试脚本执行过程

注意

  1. [ ]表示条件测试。注意这里的空格很重要。要注意在"[ 666 ]"前面和后面都必须要有空格
  2. 在shell中,then和fi是分开的语句。如果要在同一行里面输入,则需要用分号将他们隔开。
  3. 注意if判断中对于变量的处理,需要加引号以免一些不必要的错误。没有加双引号会在一些含空格等的字符串变量判断的时候产生错误。比如[ -n "$var" ]如果var为空会出错
  4. 判断是不支持浮点值的
  5. 如果只单独使用>或者
  6. 默认,运行if语句中的命令,所产生的错误信息。仍然出现在脚本的输出结果中
  7. 使用-z或者-n来检查长度的时候,没有定义的变量也为0
  8. 空变量和没有初始化的变量可能会对shell脚本测试产生灾难性的影响,因此在不确定变量的内容的时候,在测试号前使用-n或者-z测试一下
  9. $?变量包含了之前执行命令的退出状态(最近完成的前台进程)(可以用于检测退出状态)

模式匹配:case

前言:shell编程中if和case都是用来做流控的。

案例1:简单的模式匹配

邀请用户输入待删除用户名。询问用户,确定要继续删除吗 yes/no: y

if写法:

#!/bin/bash

#name

#time

#1请输入删除的用户名:

read -p "please input a username : " user

#2请用户确认是否删除

read -p "are you sure?[y/n]: " action

if [ "$action" = "y" -o "$action" = "Y" ] ;then

userdel -r $user

echo "$user is deleted!"

else

echo "thank you” fi

case 语法结构:

case 变量 in

模式1)

命令序列1

;;

模式2)

命令序列2

;;

模式3)

命令序列3

;;

*)

无匹配后命令序列

;;

esac

case写法:

#!/bin/bash

#name

#time

#1请输入删除的用户名:

read -p "please input a username : " user

#2请用户确认是否删除

read -p "确认删除吗?[yes/no]" action

#3 case 流控写法

case "$action" in

YlylYES|yes|Yes|YeS|YEs)

userdel -r $user

echo "$user is deleted!"

;;

*)

echo "thank you"

;;

esac

案例2:简单的JumpServer

需求:由于工作中,我们需要管理N多台服务器。那么访问服务器就是一件繁琐的事情。通过shell编程,编写跳板程序。当我们需要访问服务器时,看一眼服务器列表名,按一下数字,就登录成功了。岂不美哉。

跳板主机,运行跳板脚本。弹出数十台服务器名的菜单

1) mysql1

2) mysql2

3) bj-web1

h) help

q) exit

用户请选择要连接的主机[1-3]:1

Last login: Sun Sep 6 04:18:01 2015 from 192.168.122.1

[root@localhost ~]$ 连接成功!!!

演示:

#!/usr/bin/bash

#定义目标主机IP

web1=192.168.122.152

web2=192.168.122.128

mysql1=192.168.122.88

#打印跳转菜单

cat

1.WEB1

2.WEB2

3.MYSQL1

EOF

#读取用户输入

read -p "input number: " num

#判断用户选择

case $num in

1)

ssh alice@$web1

;;

2)

ssh alice@$web2

;;

*)

echo '123'

esac

案例3:系统管理工具箱

前言:linux提供的丰富的管理命令,用户管理,内存管理,磁盘管理,进程管理,日志管理,文件管理,软件管理,网络管理等等数十个工具包。如果你能通过shell编程,把他们编写到一个程序里,想用某些功能,只需要按回车,就能完成。岂不美哉。

Command action

h 显示命令帮助

f 显示磁盘分区

d 显示磁盘挂载

m 查看内存使用

u 查看系统负载

q 退出程序

Command (h for help): m

total used free shared buffers cached

Mem: 7628 840 6788 0 29 378

Swap: 2047 0 2047

演示:

#!/usr/bin/bash

#打印菜单

cat

h. help

f.disk partation

d. filesystem mount

m. memory

u. system load

q.exit

EOF

#读取用户输入,进行模式匹配

read -p "please input [h for help]: " action

case "$action" in f)

fdisk -I

;;

d)

df -hT

;;

m)

free -m

;;

u)

uptime

;;

q)

exit

;;

"")

;;

*)

echo "error"

;;

你可能感兴趣的:(学习,笔记,前端)