linux中shell的流程和循环控制

shell流程控制

任何编程都离不开判断(流控)

流程注意

1.[]表示条件测试,这里的空格很重要
2.在shell中,then和fi是分开的语句,如果要放在一行,需要分号隔开
3.注意if判断中对变量的处理,需要加引号
4.判断不支持浮点值
5.如果单独使用<或者>系统会认为是重定向,如果要使用,要对这些符号转意
6.默认运行if语句中的命令,所产生的错误信息,会出现在脚本的输出结果中,一般会使用&>/dev/null
7.使用-n或者-z来检查长度时候,没有定义的变量也为0
8.空变量和没有初始化的变量会对shell脚本造成灾难性的影响,再不确定变量内容时,可以使用-n或者-z测试一下
9.$?变量包含了之前执行命令的退出状态,最近完成的前台进程

调试脚本
sh -n 文件名    //仅调试脚本中的语法错误
sh -x 文件名   //逐句语句追踪
sh -v 文件名   //显示执行过程详细信息
sh -vx 文件名   //以调试的方式执行,查询整个执行过程,第一行是计算机看到的
											   第二行是计算机执行的
											   第三行是计算机输出的

条件结构

test 条件
条件为真返回0;条件为假返回1
[ 条件表达式 ]
[[ 条件表达式 ]]

test 能够理解3种类型的表达式 
文件测试
字符串比较
数字比较

数值比较

[ -gt ]  大于
[ -lt ]  小于
[ -eq ]  等于
[ -ne ]  不等于
[ -ge ]  大于等于
[ -le ]  小于等于

文件测试

-f filename :当filename存在时返回真
-b filename :当filename存在并且是块文件时返回真
-d pathname :当pathname存在并且是一个目录时返回真
-h filename :当filename存在并且是符号链接文件时返回真,软连接
-c filename :当filename存在并且是字符文件时返回真
-e pathname :当由pathname指定的文件或目录存在时返回真
-g pathname :当由pathname指定的文件或目录存在并且设置了SGID位时返回真  (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的用户拥有时返回真
-G pathname :当由pathname存在并且属于当前进程的有效用户id的用户的用户组时返回真

字符串比较

比较字符串的时候字符串建议加上双引号
=:等于
!=:不等于
-z:判断字符长度是为0
-n:判断字符长度不是为0

当条件测试比较复杂时,需要多个条件同时成立,就需要混合条件测试
逻辑的(and)与(or)
				
&&逻辑的and的意思,-a,两个条件同时完成时成立,为真
||逻辑的or的意思,-o,两个条件一个成立,为真
				
表示方法:
[ 条件一 -a 条件二 ]
[[ 条件二 && 条件一 ]]
[ 条件一] && [条件二 ]
				
[ 条件一 -o 条件二 ]
[[ 条件二 || 条件一 ]]
[ 条件一] || [条件二 ]

if语句

单分支结构

if [ 条件 ] ; then
	符合该条件执行的语句
fi

双分支结构

表示方法一:
if [ 条件 ] 
then
	符合该条件执行的语句
else
	不符合该条件执行的语句
fi
				
表示方法二:
if 命令
then
	命令返回结果为真
else
	命令返回结果为假
fi

多分支结构

if [ 条件1 ] 
then
	符合该条件执行的语句
							
elif [ 条件2 ]
then	
	符合该条件执行的语句
							
elif [ 条件3 ]
then	
	符合该条件执行的语句
						
else
	不符合该条件执行的语句
fi

嵌套结构

if[条件测试1] 
then
	命令序列			
	if[条件测试2]
	then
		命令序列				
	else
		命令序列
	fi				
else
	命令序列
fi

case语句

格式

case 变量 in 
模式1)
	命令序列1
	;;			
模式2)
	命令序列2
	;;			
模式3)
	命令序列3
	;;		
*)
	无匹配命令序列后
	;;
esac

shell循环控制

for循环

for 变量名  in 取值列表 
do
	循环体
done
for循环优化脚本    {}&:并发      在do和done之间加{}&:

for 变量名  in 取值列表 
do
{
	循环体
}&
done

while循环

===当条件测试成立(条件测试为真),执行循环体

do
	循环体
done
===将文件内的语句输出到循环体中
while read user
do
	循环体
done < 文件.txt

until循环

=======当条件测试成立,条件测试为假视为成立,执行循环体

until 条件测试
do
	循环体
done		

expect交互

yum -y install expect tcl tcl-devel      //安装expect交互
vim expect.exp       //运行脚本使用命令:expect expect.exp
#!/usr/bin/expect
spawn ssh root@ip地址       //启动系统中需要交互的程序
			
expect 
{
	"yes/no" {send "yes\r"; exp_continue}    //send发送回答,\r代表回车  
											//exp_continue,在"yes/no"没出现时忽略这句话
	"passwd:" {send "密码\r"} 
}
	interact            //停留在当前程序位置
			
========================================================
bash调用expect语言
/usr/bin/expect <<-EOF
expect语言内容
expect eof             //运行结束后,离开当前程序位置,返回之前工作位置
EOF

shell循环控制

shift
位置参数可以用shift命令左移。
如shift 3表示原来的$4现在变成$1

break
结束并退出本次循环

continue 
在循环中不执行continue下面的代码,转而进入下一轮循环

exit
退出脚本,结束该程序