bash之条件测试if/else
bash之条件测试:
if/then结构
条件测试(CONDITION):
test EXPRESSION:测试条件表达式正确否
[ EXPRESSION ]
[[ EXPRESSION ]]
COMMAND
测试表达式:
1)整数测试
2)字符串测试
3)文件测试
整数测试:A, B
A -gt B: 大于
A -ge B: 大于等于
A -eq B: 等于
A -lt B: 小于
A -le B: 小于等于
A -ne B: 不等于
例:
字符串测试:A, B
A > B
A < B
A >= B
A <= B
A == B或A = B: 等值比较
A != B: 不等于
-z A: 判断A是否为空,空则为真,不空为假
-n A: 判断A是否不空,不空为真,空为假
条件取反:
! CONDITION
条件测试语法:
单分支:
if CONDITION; then
CMD1
CMD2
fi
例:传递一个参数给test.sh,判断是否为偶数,是则打印,否则不打印
test.sh 5
#!/bin/bash
shuzi=$1
if [ $[$shuzi%2] -eq 0 ];then
echo $shuzi
fi
条件表达式为双中括号[[ $shuzi%2 -eq 0 ]]也可以
bash -n test.sh
检查脚本有无语法错误
bash -x test.sh 10
调试执行,一步一步执行,打印执行步骤,最后打印执行结果
例:传递一个参数给脚本,而后以此参数为用户名,添加此用户
useradd.sh
#!/bin/bash
username=$1
if ! id $username ;then
useradd $username
fi
执行bash -n useradd.sh检查脚本是否存在语法错误
bash -x useradd.sh aaa
打印执行过程,最终打印执行结果
if可以嵌套:
if CONDITION; then
if CONDITION2; then
CMD
fi
fi
条件取反:
! COMMAND
双分支:
if CONDITION; then
分支1
else
分支2
fi
练习2:
传递两个整数给脚本,返回其较大者
test.sh
#!/bin/bash
if $1 -gt $2;then
echo $1
else
echo $2
fi
bash -n
练习3:写一个脚本
1)传递一个参数给脚本,此参数为用户名
2)如果用户存在的话,则执行如下任务
a)如果用户的id号小于500,显示其为管理员或系统用户
b)否则,显示为普通用户
3)如果用户不存在,则添加
#!/bin/bash
if id $1 &> /dev/null;then
userid=`id -u $1`
if [ $userid -lt 500 ];then
echo "$1 is sysadmin or sysuser."
else
echo "$1 is a common user"
fi
else
useradd $1
if [ $? -eq 0 ];then
echo "Add user $1"
else
echo "Fail to add $1"
fi
fi
&<:标准输出和错误输出都输出进黑洞/dev/null
useradd命令是管理员才能使用的命令,所以有可能执行失败,故用判断$?
多分支的if语句:
if CONDITION1-TRUE;then
分支1
elif CONDITION2-TRUE;then
分支2
elif CONDITION3-TRUE;then
分支3
...
else
分支n
fi
例:
练习1:传递一个参数给脚本
如果参数为quit,则显示说要退出脚本;
如果参数为yes,则显示说继续;
否则,则显示为无法识别;
test.sh
#!/bin/bash
if [ $1 == "quit" ];then
exit
elif [ $1 == "yes" ];then
echo "continue"
else
echo "not find age"
fi
练习2:传递一个用户名参数给脚本
(1) 如果用户的id号为0,则显示为管理员;
(2) 如果用户的id号大于6000,则显示为guest;
(3) 如果用户的id号大于500,则显示为普通用户;
(4) 如果用户的id号大于0, 则显示为系统用户;
(5) 否则,无法识别;
练习3:写一个脚本;
(1) 传递一个磁盘设备文件给脚本;
(2) 判断此设备是否存在;如果存在,则清除此设备上的所有分区;
(3) 否则,则无此设备;
COMMAND用作条件:
(1) 使用命令执行结果;
(a) 使用命令引用 ``
(b) 使用比较操作符
例:[ `id -u $username` -lt 500 ]
userid=`id -u $username`
[ $userid -lt 500 ]
(2) 使用命令的退出状态码
(a) 先运行命令
(b) 退出状态码
引用方式两种:
(a) if COMMAND; then
注意:COMMAND不能被命令引用;COMMAND的执行结果通常没有意义,所以其结果通常(&>)被定向至/dev/null
(b) 先执行命令,后判断退出状态码是否为0
COMMAND
if [ $? -eq 0 ]
条件测试:
文件u测试:$file
-e $file:是否存在,存在则为真 [ -e /tmp/aaa ]
-a $file:同上,弃用
-f $file:文件是否存在,且为普通文件
-d $file:是否存在且为目录
-h $file:是否存在且为符号链接文件
-L $file:同上
-b $file:是否存在且为块设备文件
-c $file:是否存在且为字符设备文件
-S $file:是否存在且为套接字文件
-p $file:是否存在且为管道文件
-r $file:当前用户对此文件是否拥有读权限
-w $file: 写权限
-x $file: 执行权限
-u $file:文件是否拥有suid权限
-g $file:文件是否拥有sgid权限
-k $file:文件是否拥有sticky权限
-O $file:当前用户是否为文件的属主
-G $file:当前用户是否属于文件的属组
-N $file:文件自从上一次被读取之后,是否被修改过
$f1 -nt $f2:文件f1是否比文件f2新
$f1 -ot $f2:文件f1是否比文件f2旧
$f1 -ef $f2:f1和f2是否为同一个文件的硬链接
练习:写一个脚本,传递一个文件路径参数给脚本
(1) 存在,则显示有此文件;
(2) 否则,则显示无此文件
练习:写一个脚本,传递一个文件路径参数给脚本
(1) 如果脚本无参数,则显示必须给至少一个参数,退出脚本;退出码5;
(2) 路径指向的文件如果不存在,则直接退出脚本;退出码为6;
(3) 判断文件类型:
(a) 如果是普通文件,则显示为"common file";
(b) 如果是目录,则显示为"directory";
(c) 如果是符号链接,则显示为"symbolic link file";
(d) 如果是块设备,则显示为“block device file";
(e) 如果是字符设备,则显示为"character device file";
(f) 否则,则显示为“unkown”;
#!/bin/bash
if [ $# -lt 1 ];then
echo "At least one argument"
exit 5
fi
if [ ! -e $1 ];then
echo "No such file"
exit 6
fi
if [ -f $1 ];then
echo "common file"
elif [ -d $1 ];then
echo "directory"
elif [ -L $1 ];then
echo "Symbolic file"
elif [ -b $1 ];then
echo "block device"
elif [ -c $1 ];then
echo "character device"
else
echo "unknown type."
fi
$#是脚本传递的参数个数
练习:写一个脚本,其使用格式如下所示(其中所有的script.sh均为用户给定的脚本名称,其要跟随脚本名称变化):
script.sh {start|stop|restart|status}
(1) 调用时至少传递一个参数;否则,则显示帮助信息,并退出脚本;
(2) 如果参数为“start”, 则创建空文件/var/lock/subsys/script.sh,并显示“starting script.sh successfully.”;
(3) 如果参数为“stop”,则删除空文件/var/lock/subsys/script.sh,并显示“stopping script.sh successfully.”;
(4) 如果参数为“restart”,则删除空文件/var/lock/subsys/script.sh,并显示“stopping script.sh successfully.”;而后重新创建之,并显示“restarting script.sh successfully.”;
(5) 如果参数为“status”,则
(a) 如果文件/var/lock/subsys/script.sh文件存在,则显示“running”;
(b) 否则,则显示为"stopped"
(6) 其它任意参数,均显示帮助信息后退出;帮助信息格式为命令使用格式;
#!/bin/bash
#
# chkconfig: 2345 95 5
# description: test service script
#
prog=`basename $0`
lockfile=/var/lock/subsys/$prog
if [ $# -lt 1 ]; then
echo "Usage: $prog {start|stop|restart|status}"
exit 1
fi
if [ "$1" == 'start' ]; then
if [ -e $lockfile ]; then
echo "$prog is aleady running."
exit 1
else
touch $lockfile
echo "Starting $prog succefully."
fi
elif [ "$1" == 'stop' ]; then
if [ -e $lockfile ]; then
rm -f $lockfile
echo "Stopping $prog succefully."
else
echo "$prog is not running."
exit 1
fi
elif [ "$1" == 'restart' ]; then
if [ -e $lockfile ]; then
rm -f $lockfile
echo "Stopping $prog succefully."
touch $lockfile
echo "Starting $prog succefully."
else
touch $lockfile
echo "Starting $prog succefully."
fi
elif [ "$1" == 'status' ];then
if [ -e $lockfile ];then
echo "$prog is running."
else
echo "$prog is stopped."
fi
else
echo "Usage: $prog {start|restart|status|stop}"
exit 1
fi
组合测试条件:
给条件添加逻辑操作符:
或:-o: [ -z "$hostname" -o "$hostname" == 'localhost' ]
-z "$hostname": 判断字符串是否为空
与:-a: [ $uid -gt 0 -a $uid -lt 500 ]
非:[ ! EXPRESSION ]
练习:写一个脚本,取得当前的主机名,判断
(1) 如果主机名为空或为"localhost",则将其命名为stuX.lianshu.com;
(2) 否则,则显示主机名即可;
#!/bin/bash
hostname=`hostname`
if [ -z "$hostname" -o "$hostname" == "localhost"];then
hostname stuX.lianshu.com
#echo "stuX.lianshu.com" > /proc/sys/kernel/hostname
else
echo "The hostname is: $hostname"
fi
练习2:写一个脚本,传递一个参数给脚本;此参数为用户名
(1) 如果用户不存在,则直接退出脚本;
(2) 如果用户存在,
id=0,则显示为“system admin”
0<id<500,则显示为“system user”
id>=500,则显示为“Common user.”
#!/bin/bash
#
if ! id $1 &> /dev/null; then
echo "No such user."
exit 1
fi
uid=$(id -u $1)
if [ $uid -eq 0 ]; then
echo "Sys Admin."
elif [ $uid -gt 0 -a $uid -lt 500 ];then
echo "Sys User."
else
echo "Common User."
fi
练习3:写一个脚本,传递一个参数给脚本;此参数为用户名
(1) 如果用户不存在,则直接退出脚本;
(2) 如果用户的id号大于等于500,且其shell为“以sh结尾的”类型,则显示“a user can log system.”;否则,显示用户无法登录;
#!/bin/bash
#
if ! id $1 &> /dev/null; then
echo "No such user."
exit 1
fi
if [[ `id -u $1` -ge 500 ]] && [[ `grep "^$1\>" /etc/passwd | cut -d: -f7` =~ /bin/.*sh$ ]]; then
echo "a user can log system."
else
echo "a user cannot log."
fi
^$1\>: (^root\>)以root开头,且词尾锚定,排除包含root字符的,例如rootab
=~为模式匹配
组合测试条件:短路操作符
与:COMMAND1 && COMMAND2
COMMAND1的退出转态结果为假,则COMMAND2不用运行,则有最终结果
或:COMMAND1 || COMMAND2
COMMAND1的退出转态结果为真,则COMMAND2不用运行,则有最终结果
非:! COMMAND
例:[ ! -d /tmp/test ] && mkdir /tmp/test
[ -d /tmp/test ] || mkdir /tmp/test
练习4:写一个脚本,完成如下任务:
(1) 如果httpd进程或nginx进程处于运行中,则显示“web server started.”,并显示其监听的端口;
(2) 否则显示“no web server.”;
if pidof httpd &> /dev/null || pidof nginx &> /dev/null;then
echo "web server started."
else
echo "no web server."
交互式脚本:
read [OPTIONS] [name ...]
-p "PROMPT": 输入过程中,想删除,则必须按ctrl+delete,单独的delete键是执行不了删除操作的
read -p "pls input:" aa
-t #: 超时时间
read -p "pls input:" -t 2 aa
给变量以默认值:
[ -z "$VAR" ] && VAR=VALUE
练习1:显示如下菜单给用户
cpu) show cpu infomation;
mem) show memory infomation;
disk) show disk infomation;
*) quit
提示用户键入选项:
(1) cpu: 显示CPU相关的信息
(2) mem: 显示内存相关的信息
(3) disk: 列出磁盘设备
(4) 其它任何信息,即为退出脚本
#!/bin/bash
#
cat << EOF
cpu) show cpu infomation;
mem) show memory infomation;
disk) show disk infomation;
*) quit
=================================================================
EOF
read -p "Your choice: " choice
if [[ "$choice" == 'cpu' ]]; then
lscpu
elif [[ "$choice" == 'mem' ]]; then
free -m
elif [[ "$choice" == 'disk' ]]; then
fdisk -l /dev/sd[a-z]
else
echo "quit"
exit 0
fi
case语句:
简洁版的多分支if语句
语法格式:
case 变量引用 in
PATTERN1)
分支1
;;
PATTERN2)
分支2
;;
...
*)
分支n
;;
esac
PATTERN可使用通配符:
*:任意长度的任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或者b
练习1:写一个脚本,使用tar工具把/etc目录备份至/backup目录中,名字为/backup/etc-日期时间.tar.{xz|bz2|gz};
(1) 显示如下菜单
xz) xz compress tool
gzip) gzip compress tool
bzip2) bzip2 compress tool
*) wrong choice and quit
(2) 根据用户选择的工具,执行相应操作;如果用户没有键入任何数据,则默认使用xz;
#!/bin/bash
cat<<EOF
xz)xz compress tool
gzip)gzip compress tool
bzip2)bzip2 compress tool
*)wrong choice and quit
=======================================================
EOF
read -t 5 -p "pls input the choice:" command
[ -z $command ] && command="xz"
! [ -d /backup ] || mkdir /backup
file_path=/backup/etc"-$(date +%Y%m%d%H%M).tar"
echo $file_path
case $command in
"xz")
echo "xz"
#tar -Jcf $file_path.xz /etc/*
;;
"gzip")
echo "gzip"
#tar -zcf $file_path.gz /etc/*
;;
"bzip2")
echo "bzip2"
#tar -jcf $file_path.bzip2 /etc/*
;;
*)
echo "wrong choice"
;;
esac
bash之条件测试if/else的更多相关文章
- bash Shell条件测试
3种测试命令: test EXPRESSION [ EXPRESSION ] [[ EXPRESSION ]] 注意:EXPRESSION前后必须有空白字符 bash的测试类型 数值测试: -eq: ...
- bash编程-条件测试
Shell脚本中经常需要判断某情况或者数据是否满足,需要由测试机制来实现. 测试方式 echo $?查看命令执行状态返回值 bash脚本中可以自定义返回值exit n(n为自己指定的状态码),shel ...
- shell条件测试test
shell条件测试可以通过以下两种方式: test 参数 测试内容 [ 参数 测试内容 ] 一.测试文件类型: test -e 文件名 (测试文件是否存在) [ - ...
- Linux Shell 03 条件测试
条件测试 方式一:在Bash中 test命令和[]是等价的. test命令: if test $n1 -eq $n2 then echo "The two number are equal& ...
- Bash中的测试——test, [], [[]], (())
转自: http://blog.csdn.net/u013961718 https://www.shiyanlou.com/courses/running test 和 [ ] test是一条内置命令 ...
- shell脚本进阶之条件测试与条件语句
接着上篇博客,今天整理一下关于条件测试和条件语句方面的知识. shell脚本进阶之条件测试 在编写shell脚本时,经常需要对一些条件进行判断,可以使用测试命令test辅助完成测试过程.t ...
- 【转】shell学习笔记(四)——条件测试
1 test 条件检测 当我要检测系统上面某些文件或者是相关的属性时,利用 test 这个命令来工作真是好用得不得了, 举例来说,我要检查 /home/oracle/zy是否存在时,使用: test ...
- 【转】shell学习笔记(三)——引用变量、内部变量、条件测试、字符串比较、整数比较等
1.env显示当前的环境变量 2.PS1='[\u@\h \w \A] \$' 可以设置bash的命令与提示符. 3.echo $$ 显示当前bash的PID号 4.echo $?显示上一条指令的回传 ...
- Shell编程-条件测试 | 基础篇
什么是Shell Shell是一个命令解释器,它会解释并执行命令行提示符下输入的命令.除此之外,Shell还有另一个功能,如果要执行多条命令,它可以将这组命令存放在一个文件中,然后可以像执行Linux ...
随机推荐
- NodeJS学习视频
腾讯课堂初级课程 https://ke.qq.com/webcourse/index.html#course_id=196698&term_id=100233129&taid=1064 ...
- jeecg308自定义使用getDataGridReturn方法分页失效问题
DataGrid dataGrid = new DataGrid(); dataGrid.setPage(p); dataGrid.setRows(r); dataGrid.setOrder(&quo ...
- Java基础:(四)继承
一.访问权限 java中有三个访问权限修饰符private:protected:public和一个默认default(不加修饰符). 如果子类的方法覆盖了父类的方法,那么子类中该方法的访问级别不允许低 ...
- HTML5:使用postMessage实现Ajax跨域请求
HTML5:使用postMessage实现Ajax跨域请求 由于同源策略的限制,Javascript存在跨域通信的问题,典型的跨域问题有iframe与父级的通信等. 常规的几种解决方法: (1) do ...
- 文件系统结构-《循序渐进linux》
1.目录结构 很多linux的发行版都遵循FSSTND标准,这一标准仅包含系统最基本的文件. /dev 设备文件 /bin 可执行的二进制文件 /opt /root 超级用户的主目录 /home 每个 ...
- (笔记)快速入门PADS logic 到 layout
以前从未接触过画板,先是硬着头皮边学边操作<Layout2007中文教程之PADS_Logic>,刚好在中秋节前把这个教程从头到尾通学了一遍,随后感觉这个教程有了方方面面但没有工程的系统性 ...
- 用Python完成根据日期计算是星期几
import datetime def week(year,month,day): someday=dayetime.date(year,month,day) result={ "0&quo ...
- POJ 3260 The Fewest Coins 最少硬币个数(完全背包+多重背包,混合型)
题意:FJ身上有各种硬币,但是要买m元的东西,想用最少的硬币个数去买,且找回的硬币数量也是最少(老板会按照最少的量自动找钱),即掏出的硬币和收到的硬币个数最少. 思路:老板会自动找钱,且按最少的找,硬 ...
- 在广州学习PHP零基础可以学习吗?
PHP现今作为互联网运用很广泛的编程语言,市场需求量也越来越高,而PHP开发工程师的薪资也是一路水涨船高,更多的人看到了PHP的发展前景,纷纷都想投入到PHP的开发大军中来,那么对于很多转行或者零基础 ...
- BZOJ 3130: [Sdoi2013]费用流 网络流+二分
3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1230 Solved: ...