任何编程都离不开判断(流控)
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 [ 条件 ] ; 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 变量 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
模式3)
命令序列3
;;
*)
无匹配命令序列后
;;
esac
for 变量名 in 取值列表
do
循环体
done
for循环优化脚本 {}&:并发 在do和done之间加{}&:
for 变量名 in 取值列表
do
{
循环体
}&
done
===当条件测试成立(条件测试为真),执行循环体
do
循环体
done
===将文件内的语句输出到循环体中
while read user
do
循环体
done < 文件.txt
=======当条件测试成立,条件测试为假视为成立,执行循环体
until 条件测试
do
循环体
done
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
shift
位置参数可以用shift命令左移。
如shift 3表示原来的$4现在变成$1
break
结束并退出本次循环
continue
在循环中不执行continue下面的代码,转而进入下一轮循环
exit
退出脚本,结束该程序