shell编程之测试,判断,循环
测试,判断,循环条件测试:
判断某需求是否满足,需要由测试机制来实现;
如何编写测试表达式以实现所需的测试;
(1)执行命令,并利用命令状态返回值来判断;
$?:上一个命令的返回值
0:成功
1-255:失败
grep "^&" /etc/init.d/functions &> /dev/null
echo $?返回0表示有空白行,测试成功;
(2)测试表达式;
测试方法一:
test expression
test 2>3
echo $?
test 2:是否大于; (单中括号中需要转义)
和 b ]
[ a < b ]
[ "a" > "b" ]
[ "a" < "b" ]
[[ "a" > "b" ]] 真
[[ "a" < "b" ]] 假
文件测试:
存在性测试,存在为真,不存在为假;
-a file同-e
-e file
[ -e /etc/rc.d/rc.sysinit ]
存在性及类型测试:
-b:是否存在且为块设备;是则为真;
[ -b /dev/sda ]
-c:是否存在且为字符设备文件;
-d:是否存在且为目录文件;
-f:是否存在且为普通文件;
-h或者-L:是否存在且为符号链接文件;
-p:是否存在且为管道文件;
-S:是否存在且为套接字文件;
文件权限测试:
-r:是否存在且对当前用户可读;
-w:是否存在且对当前用户可写;
-x:是否存在且对当前用户可执行;
特殊权限测试:
-u:是否存在且拥有suid权限;
[ -u /usr/bin/su ]
-g:是否存在且拥有sgid权限;
[ -u /usr/bin/passwd ]
-k:是否存在且拥有sticky权限;
[ -k /tmp ]
文件是否有内容:
-s:有内容为真,空则为假;
时间戳测试:
-n:文件从上一次读操作后是否被修改过;
从属关系测试:
-O:当前用户是否为文件的属主;
-G:当前用户是否属于文件的属组;
双目测试,文件新旧比较测试:
file1 -ef file2:file1与file2是否指向同一个文件系统的相同inode的硬链接;
file1 -nt file2:file1是否新于file2; (newer than)
file1 -ot file2:file1是否旧于file2; (older than)
文件的新旧比较的主要使用场景是判断文件是否本更新或增量备份时;
逻辑测试,组合测试条件:
逻辑运算符:
COMMAND1 && COMMAND2
COMMAND1 || COMMAND2
!COMMAND
逻辑运算:
运算数:真(true,yes,on,1)
假(false,no,off,0)
与:
1 && 1 = 1
1 && 0 = 0
0 && 0 = 0
0 && 0 = 0
或:
1 || 1 = 1
1 || 0 = 1
0 || 1 = 1
0 || 0 = 0
非:
!1 = 0
!0 = 1
短路法则:
COMMAND1 && COMMAND2
COMMAND1为假,则COMMAND2不会再执行;
否则,COMMAND1为真,则COMMAND2必须执行;
COMMAND1 ||COMMAND2
COMMAND1为真,则COMMAND2不会执行;
否则,COMMAND1为假,则COMMAND2必须执行;
[ -O file ] && [ -r file ]
id user3 &> /dev/null && exit 0 || useradd user3
如果id user3为真则执行exit,如果为假,则执行useradd;
逻辑测试符:
expression1 -a expression2
expression1 -o expression2
!expression
[ -O file -a -x file ]
[ ! -e /var/log/messages ] 测试值为真的表达式在使用逻辑非后,表达式为假;
在shell中,流程控制分为两大类:
一类是:判断选择;(if,case)
一类是:循环;(for,while,until,select)
if判断结构:
if expression;then
COMMAND
fi
if是最简单的判断语句,如果测试结果为真,则执行COMMAND;(单向选择)
if/else判断结构:
if expression;then
COMMAND
else
COMMAND
fi
如果if后的判断为真,则执行then后的命令;否则,执行else后的命令;
if/elif/else判断结构:
if expression1;then
COMMAND1
elif expression2;then
COMMAND2
else
COMMAND
fi
注意:多个条件可能同时为真,只会执行第一次测试为真的分支;
case判断结构:
case VARIABLE in
var1) COMMAND1 ;;
var2) COMMAND2 ;;
var3) COMMAND3 ;;
*) COMMAND ;;
esac
从上到下依次比较$VAR和var1、var2..是否相等,如果匹配则执行后面的命令,没有匹配的则默认匹配最后的*);
循环执行:将一段代码重复执行0、1或多次;
进入条件:条件满足时才进入循环;
退出条件:每个循环都应该有退出条件,以有机会退出循环;
bash脚本有3种循环方式:
for循环
while循环
until循环
带列表的for循环:
for VARIABLE in LIST;do
循环体
done
进入条件:只要列表有可用元素即可进入循环;
退出条件:列表中的元素遍历完成;
LIST的生成方式:
(1)直接给出;
(2)整数列表;
(a):{start..end}
echo {1..10}
echo {a..z}
(b):seq
seq LASTseq 10
seq FIRST LASTseq 5 10
seq FIRST INCREMENT LAST seq 1 2 10; seq 2 2 10
seq 100 -2 10 逐个-2到10
(c):返回列表的命令
(d):通配符
(e):变量引用
$@,$*
不带列表的for循环:
for VARIABLE
do
COMMAND
done
使用不带列表的for循环时,通过参数的方式给for循环传递变量值;
vim for01.sh
#!/bin/bash
for VARIABLE
do
echo -n "$VARIABLE"
done
带参数执行:
#bash for01.sh 1 2 3
1 2 3
语法虽然可以工作,但是可读性较差,所以不建议使用;可以用特殊变量$@改写上述结构,功能完全一样;
vim for02.sh
#!/bin/bash
for VARIABLE in $@
do
echo -n "$VARIABLE"
done
类C的for循环:
for ((expression1;expression2;expression3))
do
COMMAND
done
expression1为初始化语句,一般用作变量定义和初始化;
expression2为判断表达式,用于测试表达式是否为真,为真则继续,为假则退出;
expression3用于变量值修改赋值,并影响循环行为;
vim for03.sh
#!/bin/bash
for ((i=1;i
页:
[1]