bahs脚本条件判断和执行
变量:
局部变量
本地变量
环境变量
特殊变量
位置参数变量
数据类型
字符型
数值型
算数运算
运算符 : =,-,*,/,%,**
let VAR=算数运算
expr $num1 op $num2
$[算数运算]
$((算数运算))
增强型赋值
变量做某种运算后存回至此变量中
let i=$i+*
let i+=*
let的运算符
+= -+ *= /= %=
自增
VAR=$[$VAR+1]
let VAR+=1
let VAR++
自减
VAR=$[$VAR-1]
let VAR-=1
let VAR--
条件测试
判断某需求是否满足,需要由测试机制来实现
如何编写测试表达式以实现所需求的测试
1.执行命令,利用命令的返回值来判断
echo $?
0=ture
1-255=false
2测试表达式
test 判断表达式
[ 判断表达式 ]
[[ 判断表达式 ]]
注意 判断表达式 两端必须有空白字符,否则为语法错误
bash的测试类型
数值测试
字符串测试
文件测试
数值判断表达式:数值比较
-eq 是否等于 [ $num1 -eq $num2 ]
-ne 是否不等于 [ $num1 -ne $num2 ]
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于
字符判断表达式:字符串比较
== 是否等于
!= 是否不等于
> 是否大于
< 是否小于
=~ 左侧字符是否能被右侧的模式所匹配
-z "STRING":判断指定的字符是否为空
-n "STRING":判断指定的字符是否不空
注意当引用变量做字符比较时 若其中一个变量值为空需要用双引号引起来
如:
~]# echo $name
~]# [[ tom == $name ]]
-bash: [: tom: 期待一元表达式 (判断表达式执行失败)
~] echo $?
2 (返回值为2 执行失败)
~]# [[ tom == "$name" ]] (判断表达式执行成功)
~]# echo $?
1 (返回值为1 字符不等于)
注意:
1:字符串比较最好加引号 变量加双引号 字符加单引号
2:最好在使用[[]]双中括号进行比较
文件测试:
存在性测试
-e FILE 判断文件是否存在
-a FILE 同上
存在性及类型测试
-b FILE 是否存在并且为块设备文件
-c FILE 是否存在并且为字符设备文件
-d FILE 是否存在并且为目录文件
-f FILE 是否存在并且为普通文件
-h FILE 是否存在并且为链接文件
-P FILE 是否存在并且为管道文件
-S FILE 是否存在并且为套接字文件
文件权限测试
-r FILE 是否存在并且对当前用户可读
-w FILE 是否存在并且对当前用户可写
-x FILE 是否存在并且对当前用户可执行
特殊权限测试
-u FILE 是否存在并且有suid权限
-g FILE 是否存在并且有sgid权限
-k FILE 是否存在并且有sticky权限
文件是否有内容
-s FILE 是否存在并且有内容
时间戳测试
-N FILE 文件自从上一次读取操作后是否被修改过
访问时间戳 = Access = A TIME 只有访问文件才会更新
更改时间戳 = Modify = M TIME 只有更改文件数据内容才会更新
改动时间戳 = Change = C TIME 只要文件有改动就会更新(数据,元数据)
从属关系测试
-O FILE 是否存在并且当前用户是否为文件属主
-G FILE 是否存在并且当前用户是否为文件属组
双目测试
FILE1 -ef FILE2 FILE1和FILE2是否指向同一个文件系统的相同inode
FILE1 -nt FILE2 FILE1是否新于FILE2
FILE1 -ot FILE2 FILE1是否旧于FILE2
新于和旧于就是比较两个文件的MTIME时间戳 距离当前时间更近或更远
组合条件测试
第一张方式
COMMAND1 && COMMAND2
COMMAND1 || COMMAND2
!COMMAND
[-O FILE ] && [ -r FILE ]
第二种方式
COMMAND1 -a COMMAND2 同&&
COMMAND1 -o COMMAND2 同||
[ -O FILE -a -x FILE ]
练习:将主机名保持至hostName变量中
主机名如果为空 或 为 localhost.localdomain 则改为yangyang
~]# hostName=`cat /etc/hostname`
~]# [ -z "$hostName" -o "localhost.localdomain" == "$hostName" ] && hostname yangyang
向脚本转递参数
位置参数变量
$1 = 位置参数变量中的第一个
$2 = ...
${10} = 10以上需要加{}
轮替
shift [*] 位置参数轮替
特殊变量
$0 : 脚本文件路径本身
$# : 脚本参数的个数
$* : 所有参数 (每个参数当作一个独立的字符串)
$@ : 所有参数 (所有参数当作一个完整的字符串)
过程式编程语言的代码执行顺序
顺序执行 :逐条执行
选择执行
单分支if语句
if 测试条件;then
代码分支
fi
双分支if语句
if 条件测试;then
代码分支
else
代码分支
fi
练习1 通过命令行参数给定一个用户名,判断ID号是偶数还是奇数
#!/bin/bash
id=`id -u $1`
id2=`echo "$[ $id % 2 ]"`
if [ $id2 -eq 0 ];then
echo "$1 的uid是偶数"
else
echo "$1 的uid是奇数"
fi
练习2 通过命令行参数给定两个文本文件名,如果文件不存在,则结束脚本执行
都存在时返回其中行数较多的文件并显示行数
file1=`cat $1 2>/dev/null | wc -l`
file2=`cat $2 2>/dev/null | wc -l`
if [ -f $1 -a -f $2 ];then
echo "$1 行数$file1"
echo "$2 行数$file2"
if [ $file1 -gt $file2 ];then
echo "$1 行数较多"
elif [ $file1 -eq $file2 ];then
echo "$1 = $2"
else
echo "$2 行数较多"
fi
else
for i in $1 $2;do
ls $i &>/dev/null
if [ $? -ne 0 ];then
echo "指定的"$i"文件不存在"
fi
done
exit 2
fi
循环执行
循环方式有
for 循环
while 循环
until 循环
for循环
for循环有两种格式
1 遍历列表
2 控制变量
遍历列表
for i in in; do
#statements
done
控制变量
for (( i = 0; i < 10; i++ )); do
#statements
done
进入条件 只要列表中有元素,即可进入循环
退出条件 列表中的元素遍历完成,即退出循环
list生成方式
1 直接给出
2 seq整数列表
3 可返回列表的命令
4 glob通配
5 变量引用
练习1 计算100内所有偶数之和 和 奇数之和
#!/bin/bash
#
sum=0
for i in `seq 0 2 100` ;do 将0改为1 即时奇数之和
let sum=$sum+i
done
echo "$sum"
练习2 计算所有用户id之和
#!/bin/bash
#
sun=0
uid=`cat /etc/passwd | awk -F ":" '{print $3}'`
for i in $uid ;do
let sum=$sum+$i
done
echo "$sum"
练习3 计算某个目录下所有文本文件的行数之和;并说明有多少文本文件
#!/bin/bash
read -p "请输入一个目录" dir
if [ -d "$dir" ];then
sum=0
file=`find $dir -type f | xargs ls`
for i in $file ;do
let sum=$sum+`cat $i | wc -l`
done
echo "目录下所有文本文件的行数总和$sum"
echo "这个目录下共有`find $dir -type f | xargs ls | wc -l`个目录 "
else
echo "输入正确的目录"
fi
while循环 条件为真进入循环 条件为假退出
while [[ condition ]]; do
循环体
循环控制变量修正表达式
done
until循环 和 while相反
until [[ condition ]]; do
循环体
循环控制变量修正表达式
done
99乘法表
#!/bin/bash
#
for a in {1..9};do
for b in `seq 1 $a`;do
echo -n ""$b"X"$a"=$[$a*$b] "
done
echo
done
bash脚本之用户交互
通过标准输入,从而完成变量赋值操作
read [OPTION]... [name]...
常用选项
-p 输出信息
-t 定义超时时间
脚本的状态返回值
默认是脚本中执行的最后一条命令的状态返回值,如果前面所有命令都错了 单单最后一个成功了 脚本的返回值依然为0
所以自己定义状态退出码
exit [n] n为自己指定的状态码
注意:shell进程遇到exit时,即会中止,因此整个脚本执行结束