组合测试条件
第一种方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
! COMMAND 非
如:[ -e FILE ] && [ -r FILE ]
第二种方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必须使用测试命令进行;
# [ -z “$HOSTNAME” -o $HOSTNAME "= =\"localhost.localdomain" ] && hostname www.QUAN.com 判断hostname是否为空或者是否为localhost.localdomain,如果有一个条件成立,执行hostname命令 # [ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab判断文件是否存在并且可执行
课堂练习:
1 、chmod -rw /tmp/file1 ,编写脚本/root/bin/per.sh,判断当前用户对/tmp/fiile1件 文件 是否不可读且不可写
首先vi /root/bin/per.sh编辑脚本
#!/bin/bash [ -r /tmp/file1 -a -w /tmp/file1 ] && echo "`whoami` can read and write " || echo "`whoami` can not read and write "
然后:wq存盘退出
2 、编写脚本/root/bin/nologin.sh 和login.sh, 实现禁止和充许普通用户登录系统。
vi /root/bin/nologin.sh
#!/bin/bash [ -e /etc/nologin ] && exit || touch /etc/nologin echo "disable user login "
vi /root/bin/login.sh
#!/bin/bash [ -e /etc/nologin ] && rm -f /etc/nologin echo "enable user login "
执行nologin脚本后,普通用户登录会出现:
然后在执行login脚本,会恢复正常:
使用read命令接受输入:
使用read 来把输入值分配给一个或多个shell 变量:
-p 指定要显示的提示
-t TIMEOUT
read 从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量
read -p “Enter a filename: “ FILE
条件选择if语句:
选择执行: 注意:if 语句可嵌套执行
单分支
if 判断条件:then 条件为真的分支代码
fi
双分支
if 判断条件; then 条件为真的分支代码
else 条件为假的分支代码
fi
多分支
if CONDITION1 ; then if-true elif CONDITION2 ; then if-ture elif CONDITION3 ; then if-ture else all-false fi
*逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if 语句
if实例:
根据命令的退出状态来执行命令
if ping -c1 -W2 station1 &> /dev/null; then echo 'Station1 is UP' elif grep "station1" ~/maintenance.txt &> /dev/null then echo 'Station1 is undergoing maintenance‘ else echo 'Station1 is unexpectedly DOWN!' exit 1 fi
条件判断case语句:
case 用变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
…
*)
默认分支
;;
esac
case支持glob风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b
练习:
1 、写一个脚本/root/bin/createuser.sh ,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id 号等信息
vi /root/bin/createuser.sh
#!/bin/bash if id $1 &> /dev/null ; then echo "$1 is exsit,the info is `id $1`" else useradd $1 && echo "useradd is successful ,the info is `id $1`" fi
2 、写一个脚本/root/bin/yesorno.sh ,提示用户输入yes或 或no, 并判断用户输入的是yes 还是no, 或是其它信息
vi /root/bin/yesorno.sh
#!/bin/bash echo -e "Do you agree marry me?yes or no:\c" read answer echo "your answer is $answer"
:wq存盘退出 执行yesorno脚本
3 、写一个脚本/root/bin/filetype.sh, 判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)
#!/bin/bash read -p "please input a path of the file :" files if [ -b $files ];then echo "该文件是块设备" elif [ -c $files ] ;then echo "该文件是字符设备" elif [ -f $files ];then echo "该文件是普通文件" elif [ -h $files ];then echo "该文件是符号链接文件" elif [ -p $files ];then echo "该文件是管道文件" elif [ -S $files ];then echo "该文件是套接字文件" elif [ -d $files ];then echo "该文件是目录文件" else echo "文件或目录不存在" fi
:wq存盘退出,执行脚本
4 、写一个脚本/root/bin/checkint.sh, 判断用户输入的参数是否为正整数
vi /root/bin/checkint.sh
!/bin/bash read -p "please input :" arg if [[ $arg =~ ^[[:digit:]]+$ ]] && [ $(expr $arg + 0) != 0 ] ;then echo "The number is positive integer" else echo "The number is not positive integer" fi
:wq 存盘退出,执行脚本
循环
循环执行:
将某代码段重复运行多次
重复运行多少次:
循环次数事先已知
循环次数事先未知
有进入条件和退出条件
for, while, until
for循环
for 变量名 in 列表;do
循环体
done
执行机制 :
依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环 结束
列表生成方式:
(1) 直接给出 列表
(2) 整数列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令
$(COMMAND)
(4) 使用glob,如:*.sh
(5) 变量引用;
$@, $*
添加10个用户user1-user10 ,密码同用户名
#!/bin/bash # Version: 0.1 # Description: Batch to create user # 1.File to import # 2.user1-user10 if [ -s userfile.t ]; then for i in $(cat userfile.t) do useradd $i echo $i | passwd --stdin $i > /dev/null done echo "The user has been created" else for i in $(seq 1 10) do useradd user$i echo user$i | passwd --stdin user$i > /dev/null done echo "The user has been created" fi
然后执行下脚本
如果重复执行脚本,会出现下面的提示:
创建一个删除脚本:
#!/bin/bash # Version: 0.1 # Description: Batch delete user # 1.File to import # 2.user1-user10 if [ -s userfile.t ]; then for i in $(cat userfile.t) do userdel -r $i > /dev/null done echo "The user has been deleted" else for i in $(seq 1 10) do userdel -r user$i > /dev/null done echo "The user has been deleted" fi
执行脚本看一下:
/etc/rc.d/rc3.d 目录下分别有多个以K开头和以S开头的文件 ;分别读取每个文件,以K开头的文件输出为文件加stop,以S开头的文件输出为文件名加start;“K34filename stop” “S66filename start”
编辑脚本,vi file-rc3.d
#!/bin/bash for file in `ls /etc/rc.d/rc3.d`;do if echo $file | grep -q "^S" ;then echo "$file start" elif echo $file | grep -q "^K" ;then echo "$file stop" fi done
写一个脚本,提示输入正整数n 的值,计算1+2+3+…n的总和
#!/bin/bash read -p "please input a number:" n sum=0 for i in $(seq 1 $n);do let sum+=$i done echo "the sum is $sum"
执行脚本 输入的数字表示的是 从1开始的n个数字 执行脚本相加求和
写一个脚本 ,提示请输入网络地址,如192.168.0.0 ,判断输入的网段中主机在线状态
#!/bin/bash file=`mktemp /tmp/pingip.XXXXXX` read -p "please input the ip adress :" ip i=`echo $ip | cut -d'.' -f1-3` for z in {1..255};do { ip=$i.$z ping -c1 -W1 $ip &> /del/null && (echo "$ip is up" ) && echo ip> > $file }& done sleep 1 echo "`cat $file | wc -l`online" rm -f $file &> /dev/null
打印九九乘法表
#!/bin/bash for i in {1..9};do for j in $(seq 1 $i) ;do echo -ne "${j}x${i}=$[i*j]\t" done echo done
while循环
while CONDITION; do
循环体
done
CONDITION :循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true” ,则执行
一次循环;直到条件测试状态为“false” 终止循环
因此:CONDTION 一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:CONDITION 为true; ;
退出条件:CONDITION 为false
练习
1 、求100 以内所有正整数之和
sum=0 i=0 while [ $i -le 100 ] ;do let sum+=$i let i++ done echo $sum
2、打印九九乘法表
#!/bin/bash i=1 j=1 while [ $i -le 9 ] ;do while [ $j -le $i ] ;do echo -ne "${j}x${i}=$[i*j]\t" let j+=1 done let i+=1 j=1 echo done
3、打印国际象棋棋盘
#!/bin/bash for i in $(seq 1 8);do for j in $(seq 1 8);do [ $[i%2-$j%2] -eq 0 ] && echo -ne "\033[44m \033[0m" || echo -ne "\033[47m \033[0m" let j++ done echo "" let i++ done
#!/bin/bash let x=y=1 h=8 while [ $x -le $h ];do while [ $y -le $h ];do if [ $[(x+y)%2] -eq 0 ] ;then echo -en "\033[41m \033[0m" else echo -en "\033[47m \033[0m" fi let y+=1 done echo let x+=1,y=1 done
4、利用变量RANDOM 生成10 个随机数字,输出这个10 数字,并显示其中的最大者和最小者
#!/bin/bash let i=0,min=max=$RANDOM echo "$min " while [ $i -lt 9 ];do ran=$RANDOM echo "$ran " if [ $ran -ge $max ];then let max=ran fi if [ $ran -le $min ];then let min=ran fi let i+=1 done echo "the max is $max ,the min is $min"
until循环
until CONDITION; do
循环体
done
:进入条件:CONDITION 为false
:退出条件:CONDITION 为true
循环控制语句continue
用于循环体中
continue [N] :提前结束第N 层的本轮循环,而直接进入下一轮判断;最内层为第1层
while CONDTIITON1; do CMD1 ... if CONDITION2; then continue fi CMDn ... done
控制循环语句break
用于循环体中
break [N] :提前结束第N 层循环,最内层为第1层
while CONDTIITON1; do CMD1 ... if CONDITION2; then break fi CMDn ... done
创建无限循环:
while true; do
循环体
done
until false; do
循环体
Done
练习
随机生成10 以内的数字,实现猜字游戏,提示比较大或小,相等则退出。
#!/bin/bash lim=10 let key=$RANDOM%lim read -p "please input a number less than $lim: " num until false;do if [ $num -le $lim &> /dev/null ] && [ $num -ge 0 &> /dev/null] ;then if [ $num -lt $key ];then read -p "is small,please input again: " num elif [ $num -gt $key ];then read -p "is big,please input again: " num else echo "you are right,man gave me five" break fi else read -p "error,please input a number less than ten: " num fi done
特殊用法
while 循环的特殊用法(遍历文件的每一行):
while read line; do
循环体
done < /PATH/FROM/SOMEFILE
依次读取/PATH/FROM/SOMEFILE 文件中的每一行,且将行赋值给变量line
双小括号方法,即((…)) 格式,也可以用于算术运算
双小括号方法也可以使bash Shell 实现C 语言风格的变量操作
#I=10
#((I++))
for循环的特殊格式:
for(( 控制变量初始化; 条件判断表达式; 控制变量的修正表达式))
do
循环体
done
控制变量初始化:仅在运行到循环代码段时执行一次
控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断
原创文章,作者:旧城以西,如若转载,请注明出处:http://www.178linux.com/35755
评论列表(1条)
shell脚本作为一个基本能力,需要我们多加练习,才能熟练掌握,我们可以通过写的练习总结出各个循环语句的区别,来实现对循坏语句的快速选择和应用。