linux之基础shell脚本编程2 if语句循环判断
来源:互联网 发布:国际期货软件下载 编辑:程序博客网 时间:2024/06/05 06:15
本章命令:if case while for unit break continue
4.4.4 组合测试
第一种方式
COMMAND1 && COMMAND2 并且
COMMADN1 || COMMAND2 或者
!COMMAND 非
第二种方式
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
!EXPRESSION 非
必须使用测试命令进行
[ -z "$HOSTNAME" -o $HOSTNAME == "localhost.localdomain" ] && hostname www.liuyuworld.com### 判断hostname是否为空或者hostname是"localhost.localdomain" 如果前面有一个条件成立,然后执行hostname 命令
[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab ##判断文件是否存在并且可执行
实战训练4
1、chmod -rw /tmp/file1,编写脚本/root/bin/per.sh,判断当前用户对/tmp/fiile1文件 是否不可读且不可写
#!/bin/bash[ ! -r /tmp/file1 ] && [ ! -w /tmp/file1 ] && echo "不可读写" || echo "可读写"
[root@centos7 shell]# chmod -rw /tmp/file1 [root@centos7 shell]# ll /tmp/file1 ----------. 1 root root 0 Aug 10 16:22 /tmp/file1[root@centos7 shell]# bash per.sh 可读写[root@centos7 shell]# su cent[cent@centos7 shell]$ bash per.sh 不可读写
2、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统
思路:当/etc/目录下存在 nologin 文件时,普通用户会无法登陆,因此,我们只需要通过删除或增加该文件来限制普通用户是否可登陆
[root@centos7 shell]# cat login.sh nologin.sh #!/bin/bash[ -e /etc/nologin ] && echo "`rm -f /etc/nologin` enable user login "#!/bin/bash[ -a /etc/nologin ] || touch /etc/nologinecho "disable user login "
执行 bash nologin.sh 脚本时,登陆普通用户会提示
Connecting to 172.18.16.152:22...Connection established.To escape to local shell, press 'Ctrl+Alt+]'.Connection closed by foreign host.Disconnected from remote host(centos7) at 20:11:18.
然后执行bash login.sh 脚本时,就可以直接登陆了
Connecting to 172.18.16.152:22...Connection established.To escape to local shell, press 'Ctrl+Alt+]'.Last failed login: Fri Aug 12 20:11:09 CST 2016 from 172.18.16.171 on ssh:nottyThere was 1 failed login attempt since the last successful login.Last login: Fri Aug 12 20:10:29 2016 from 172.18.16.171
五,流程控制
5.1 使用read命令来接受输入
使用read来把输入值分配给一个或多个shell变量:
-p :指定要显示的提示
-t :TIMEOUT
比如:
read -p "print a filename:" file
注意:read 从标准输入中读取值,给每一个单词分配一个变量,所有剩余单词都被分配给最后一个变量
5.2 条件选择if语句
if语句是选择执行,并且可以嵌套执行
单分支:
if 判断条件 ; then
条件为真的分支代码
fi
if [ $1 -gt 60 ];then echo "the grade is pass"fi
双分支:
if 判断条件 ; then
条件为真的分支代码
else
条件为假的分支代码
fi
if [ $1 -gt 60 ];then echo "the grade is pass"else echo "the grade is not pass"fi
多分支:
逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句
if CONDITION1; then if-true elif CONDITION2; then if-ture elif CONDITION3; then if-ture ... else all-false fi
5.3 条件判断case语句
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac
case支持glob风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b
实战训练5
1、写一个脚本/root/bin/createuser.sh,实现如下功能: 使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息
##方法一[root@centos7 test]# cat createuser.sh #!/bin/bashid $1 &>/dev/null && (echo '该用户已存在,信息为:' ; id $1) || ( useradd $1 ; echo '添加成功,信息为:' ; id $1)[root@centos7 test]# bash createuser.sh user01添加成功,信息为:uid=1005(user01) gid=1005(user01) groups=1005(user01)[root@centos7 test]# bash createuser.sh user01该用户已存在,信息为:uid=1005(user01) gid=1005(user01) groups=1005(user01)
##方法二#!/bin/bashif 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,或是其它信息
#!/bin/bashread -p "please input 'yes' or 'no' : " stringcase $string in[Yy][Ee][sS]|Y|y) echo "you input is yes" ;;[Nn][oO]|N|n) echo "you input is no" ;;*) echo "you input is other info" ;;esac
3、写一个脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)
#!/bin/bashread -p "please input a path of the file :" filesif [ -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
4、写一个脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数
#!/bin/bashread -p "please input :" argif [[ $arg =~ ^[[:digit:]]+$ ]] && [ $(expr $arg + 0) != 0 ] ;then echo "是正整数"else echo "不是正整数"fi
六,循环
循环执行:
将某代码重复运行多次
重复运行多次
循环次数事先已知
循环次数事先未知
有进入条件和退出条件
for,while,until
6.1
for循环
for 变量名 in 列表;do
循环体
done
执行机制:依次将列表中的元素赋值给"变量名";每次赋值后即执行一次循环体,直到类表中的元素耗尽,循环结束
列表生成方式:
(1) 直接给出列表
(2) 整数列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令 $(COMMAND)
(4) 使用glob,如:*.sh
(5) 变量引用: $@, $*
实战训练6
要求:用for实现
1、判断/var/目录下所有文件的类型
#!/bin/bashfor i in /var/* ;doif [ -b $i ];then echo "$i是块设备"elif [ -c $i ] ;then echo "$i是字符设备"elif [ -f $i ];then echo "$i是普通文件"elif [ -h $i ];then echo "$i是符号链接文件"elif [ -p $i ];then echo "$i是管道文件"elif [ -S $i ];then echo "$i是套接字文件"elif [ -d $i ];then echo "$i是目录文件"else echo "文件或目录不存在"fidone
2、添加10个用户user1-user10,密码同用户名
#!/bin/bash#添加10个用户for i in user{1..10} ;do id $i &> /dev/null && echo "$i 用户已存在"|| (adduser $i ;echo "$i 用户添加成功") echo $i:$i | chpasswddone
#!/bin/bash#删除10个用户for i in user{1..10} ;do id $i &> /dev/null && (userdel -fr $i ;echo "$i 删除成功") || echo "$i 删除失败,该用户肯不存在"done
3、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的 文件;分别读取每个文件,以K开头的文件输出为文件加stop ,以S开头的文件输出为文件名加start; “K34filename stop” “S66filename start”
#!/bin/bashfor i in /etc/rc.d/rc3.d/[SK]* ;doif [ $(basename $i | cut -c1) == "K" ] ;then echo "`basename $i` stop"else echo "`basename $i` start"fidone
4、写一个脚本,提示输入正整数n的值,计算1+2+3+…n的 总和
#!/bin/bashread -p "please input a number:" nsum=0for i in $(seq 1 $n);do let sum+=$idoneecho "the sum is $sum"
5、写一个脚本,提示请输入网络地址,如192.168.0.0,判 断输入的网段中主机在线状态
#!/bin/bashfile=`mktemp /tmp/pingip.XXXXXX`read -p "请输入网络地址 :" ipi=`echo $ip | cut -d'.' -f1-3`for z in {1..255};do{ ip=$i.$z ping -c1 -W1 $ip &> /dev/null && (echo "$ip is up" ) && echo ip >> $file}&donesleep 1echo "`cat $file | wc -l`在线"rm -f $file &> /dev/null
6、打印九九乘法表
#!/bin/bashfor i in {1..9};do for j in $(seq 1 $i) ;do echo -ne "${j}x${i}=$[i*j]\t" done echo done
6.2
while 循环
语法:
while CONDITION; do
循环体
done
CONDITION:循环控制条件;进入循环之前,先做一次判 断;每一次循环之后会再次做判断;条件为“true”,则执行 一次循环;直到条件测试状态为“false”终止循环
因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:CONDITION为true
退出条件:CONDITION为false
实战训练7
要求:用while实现
1、求100以内所有正整数之和
#!/bin/bashsum=0i=0while [ $i -le 100 ] ;do let sum+=$i let i++ doneecho $sum
2、通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态,统计在线主机和离线主机各多少。
#!/bin/baship=10.1.250.i=1sum=0while [ $i -lt 255 ] ;do if ping -c1 -W1 $ip$i &> /dev/null ;then let sum+=1 echo "$ip$i is up" else echo "$ip$i is down" fi let i+=1doneecho "在线主机$sum台,离线$[255-sum]主机台"
3、打印九九乘法表
#!/bin/bashi=1j=1while [ $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 echodone
4、利用变量RANDOM生成10个随机数字,输出这个10数字 ,并显示其中的最大者和最小者
#!/bin/bashlet i=0,min=max=$RANDOMecho "$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+=1doneecho "最大值是 $max ,最小值是 $min"
5、打印国际象棋棋盘
#!/bin/bashlet x=y=1h=8while [ $x -le $h ];do while [ $y -le $h ];do if [ $[(x+y)%2] -eq 0 ] ;then echo -en "\033[47m \033[0m" else echo -en "\033[40m \033[0m" fi let y+=1 done echolet x+=1,y=1done
#!/bin/bashnum=8for((i=1;i<=$num;i++)){for ((j=1;j<=$num;j++)){ if [ $[(i+j)%2] -eq 0 ];then echo -en "\033[47m \033[0m" else echo -en "\033[42m \033[0m" fi}echo}
6.3
until循环 (和while循环执行条件相反)
until CONDITION; do
循环体
done
进入条件: CONDITION 为false
退出条件: CONDITION 为true
6.4
循环控制语句continue,break
用于循环体中
continue [N]:提前结束第N层的本轮循环,而直接进入下一 轮判断;最内层为第1层
while CONDTIITON1; do CMD1 ... if CONDITION2; then continue fi CMDn ... done
break [N]:提前结束第N层循环,最内层为第1层
while CONDTIITON1; do CMD1 ... if CONDITION2; then break fi CMDn ... done
比如无限循环:
while true; do 循环体 doneuntil false; do 循环体 Done
实战训练8
1、每隔3秒钟到系统上获取已经登录的用户的信息;如果发 现用户hacker登录,则将登录时间和主机记录于日志 /var/log/login.log中,并提示该用户退出系统
#!/bin/bashusername=cent{while true ;do if who | egrep "^\b$username\b" &> /dev/null ;then who | egrep "^\b$username\b" >> /var/log/login.log echo "$username 已经登录" echo "fuck ,go out my system" | write $username else echo "$username 已经下线" fi sleep 3done}
#!/bin/bashusername=hackerexituser(){ echo "fuck you,you will exit,haha" | write $username sleep 2 pidlist=$(ps -f h -u $username | tr -s ' '|cut -d' ' -f2) for i in $pidlist ;do kill -9 $i# echo "正在结束进程" done}while true ;do if w | egrep "^\b$username\b" &> /dev/null ;then w | egrep "^\b$username\b" >> /var/login.log echo "$username 已经登录" exituser else echo "$username 已经下线" fi sleep 3done
2、随机生成10以内的数字,实现猜字游戏,提示比较大或小 ,相等则退出
#!bin/bashlim=10let key=$RANDOM%limread -p "please input a number less than $lim: " numuntil 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,you are very clever" break fi else read -p "error,please input a number less than ten: " num fidone
6.5 一些特殊用法
while循环的特殊用法(遍历文件的每一行):
while read line; do
循环体
done < /PATH/FROM/SOMEFILE
依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
练习 扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电话为62985600,并提示该用户的GECOS信息修改成功。
#!/bin/bashphone=" phone number is 62985600"pathname=/etc/passwdwhile read line;do name=`echo $line|cut -d: -f1` b=`echo $line | cut -d: -f5|wc -c` if [ $b -eq 1 ] ;then chfn -f $name -p $phone $name &>/dev/null && echo "$name信息修改成功" || echo "$name信息修改失败" fidone < $pathname
双小括号方法,即((…))格式,也可以用于算术运算
双小括号方法也可以使bash Shell实现C语言风格的变量操作 #I=10 #((I++))
for循环的特殊格式:
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式)) do
循环体
done
控制变量初始化:仅在运行到循环代码段时执行一次
控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算 ,而后再做条件判断
6.6 select 循环与菜单
select variable in list
do
循环体命令
done
select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3提示符等待用户输入
用户输入菜单列表中的某个数字,执行相应的命令
用户输入被保存在内置变量REPLY中
select是个无限循环,因此要记住用break命令退出循环,或用exit命令终止脚本,也可以按Ctrl+c退出循环
select经常和case联合使用
与for循环类似,可以省略in list,此时使用位置参数
比如
#!/bin/bashPS3="please input your chose:"list="start stop restart status exit"select k in $listdo case $k in start) echo start ;; stop) echo stop ;; restart) echo restart ;; status) echo status ;; exit) echo exit ;; *) break ;; esacdone
本章命令:if case while for unit break continue
linux之基础shell脚本编程1 基础变量赋值
linux之基础shell脚本编程3 函数数组
linux之基础shell脚本编程4 字符串操作,变量赋值,配置用户环境
4.4.4 组合测试
第一种方式
COMMAND1 && COMMAND2 并且
COMMADN1 || COMMAND2 或者
!COMMAND 非
第二种方式
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
!EXPRESSION 非
必须使用测试命令进行
[ -z "$HOSTNAME" -o $HOSTNAME == "localhost.localdomain" ] && hostname www.liuyuworld.com### 判断hostname是否为空或者hostname是"localhost.localdomain" 如果前面有一个条件成立,然后执行hostname 命令
[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab ##判断文件是否存在并且可执行
实战训练4
1、chmod -rw /tmp/file1,编写脚本/root/bin/per.sh,判断当前用户对/tmp/fiile1文件 是否不可读且不可写
#!/bin/bash[ ! -r /tmp/file1 ] && [ ! -w /tmp/file1 ] && echo "不可读写" || echo "可读写"
[root@centos7 shell]# chmod -rw /tmp/file1 [root@centos7 shell]# ll /tmp/file1 ----------. 1 root root 0 Aug 10 16:22 /tmp/file1[root@centos7 shell]# bash per.sh 可读写[root@centos7 shell]# su cent[cent@centos7 shell]$ bash per.sh 不可读写
2、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统
思路:当/etc/目录下存在 nologin 文件时,普通用户会无法登陆,因此,我们只需要通过删除或增加该文件来限制普通用户是否可登陆
[root@centos7 shell]# cat login.sh nologin.sh #!/bin/bash[ -e /etc/nologin ] && echo "`rm -f /etc/nologin` enable user login "#!/bin/bash[ -a /etc/nologin ] || touch /etc/nologinecho "disable user login "
执行 bash nologin.sh 脚本时,登陆普通用户会提示
Connecting to 172.18.16.152:22...Connection established.To escape to local shell, press 'Ctrl+Alt+]'.Connection closed by foreign host.Disconnected from remote host(centos7) at 20:11:18.
然后执行bash login.sh 脚本时,就可以直接登陆了
Connecting to 172.18.16.152:22...Connection established.To escape to local shell, press 'Ctrl+Alt+]'.Last failed login: Fri Aug 12 20:11:09 CST 2016 from 172.18.16.171 on ssh:nottyThere was 1 failed login attempt since the last successful login.Last login: Fri Aug 12 20:10:29 2016 from 172.18.16.171
五,流程控制
5.1 使用read命令来接受输入
使用read来把输入值分配给一个或多个shell变量:
-p :指定要显示的提示
-t :TIMEOUT
比如:
read -p "print a filename:" file
注意:read 从标准输入中读取值,给每一个单词分配一个变量,所有剩余单词都被分配给最后一个变量
5.2 条件选择if语句
if语句是选择执行,并且可以嵌套执行
单分支:
if 判断条件 ; then
条件为真的分支代码
fi
if [ $1 -gt 60 ];then echo "the grade is pass"fi
双分支:
if 判断条件 ; then
条件为真的分支代码
else
条件为假的分支代码
fi
if [ $1 -gt 60 ];then echo "the grade is pass"else echo "the grade is not pass"fi
多分支:
逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句
if CONDITION1; then if-true elif CONDITION2; then if-ture elif CONDITION3; then if-ture ... else all-false fi
5.3 条件判断case语句
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac
case支持glob风格的通配符:
*: 任意长度任意字符
?: 任意单个字符
[]:指定范围内的任意单个字符
a|b: a或b
实战训练5
1、写一个脚本/root/bin/createuser.sh,实现如下功能: 使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息
##方法一[root@centos7 test]# cat createuser.sh #!/bin/bashid $1 &>/dev/null && (echo '该用户已存在,信息为:' ; id $1) || ( useradd $1 ; echo '添加成功,信息为:' ; id $1)[root@centos7 test]# bash createuser.sh user01添加成功,信息为:uid=1005(user01) gid=1005(user01) groups=1005(user01)[root@centos7 test]# bash createuser.sh user01该用户已存在,信息为:uid=1005(user01) gid=1005(user01) groups=1005(user01)
##方法二#!/bin/bashif 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,或是其它信息
#!/bin/bashread -p "please input 'yes' or 'no' : " stringcase $string in[Yy][Ee][sS]|Y|y) echo "you input is yes" ;;[Nn][oO]|N|n) echo "you input is no" ;;*) echo "you input is other info" ;;esac
3、写一个脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)
#!/bin/bashread -p "please input a path of the file :" filesif [ -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
4、写一个脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数
#!/bin/bashread -p "please input :" argif [[ $arg =~ ^[[:digit:]]+$ ]] && [ $(expr $arg + 0) != 0 ] ;then echo "是正整数"else echo "不是正整数"fi
六,循环
循环执行:
将某代码重复运行多次
重复运行多次
循环次数事先已知
循环次数事先未知
有进入条件和退出条件
for,while,until
6.1
for循环
for 变量名 in 列表;do
循环体
done
执行机制:依次将列表中的元素赋值给"变量名";每次赋值后即执行一次循环体,直到类表中的元素耗尽,循环结束
列表生成方式:
(1) 直接给出列表
(2) 整数列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令 $(COMMAND)
(4) 使用glob,如:*.sh
(5) 变量引用: $@, $*
实战训练6
要求:用for实现
1、判断/var/目录下所有文件的类型
#!/bin/bashfor i in /var/* ;doif [ -b $i ];then echo "$i是块设备"elif [ -c $i ] ;then echo "$i是字符设备"elif [ -f $i ];then echo "$i是普通文件"elif [ -h $i ];then echo "$i是符号链接文件"elif [ -p $i ];then echo "$i是管道文件"elif [ -S $i ];then echo "$i是套接字文件"elif [ -d $i ];then echo "$i是目录文件"else echo "文件或目录不存在"fidone
2、添加10个用户user1-user10,密码同用户名
#!/bin/bash#添加10个用户for i in user{1..10} ;do id $i &> /dev/null && echo "$i 用户已存在"|| (adduser $i ;echo "$i 用户添加成功") echo $i:$i | chpasswddone
#!/bin/bash#删除10个用户for i in user{1..10} ;do id $i &> /dev/null && (userdel -fr $i ;echo "$i 删除成功") || echo "$i 删除失败,该用户肯不存在"done
3、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的 文件;分别读取每个文件,以K开头的文件输出为文件加stop ,以S开头的文件输出为文件名加start; “K34filename stop” “S66filename start”
#!/bin/bashfor i in /etc/rc.d/rc3.d/[SK]* ;doif [ $(basename $i | cut -c1) == "K" ] ;then echo "`basename $i` stop"else echo "`basename $i` start"fidone
4、写一个脚本,提示输入正整数n的值,计算1+2+3+…n的 总和
#!/bin/bashread -p "please input a number:" nsum=0for i in $(seq 1 $n);do let sum+=$idoneecho "the sum is $sum"
5、写一个脚本,提示请输入网络地址,如192.168.0.0,判 断输入的网段中主机在线状态
#!/bin/bashfile=`mktemp /tmp/pingip.XXXXXX`read -p "请输入网络地址 :" ipi=`echo $ip | cut -d'.' -f1-3`for z in {1..255};do{ ip=$i.$z ping -c1 -W1 $ip &> /dev/null && (echo "$ip is up" ) && echo ip >> $file}&donesleep 1echo "`cat $file | wc -l`在线"rm -f $file &> /dev/null
6、打印九九乘法表
#!/bin/bashfor i in {1..9};do for j in $(seq 1 $i) ;do echo -ne "${j}x${i}=$[i*j]\t" done echo done
6.2
while 循环
语法:
while CONDITION; do
循环体
done
CONDITION:循环控制条件;进入循环之前,先做一次判 断;每一次循环之后会再次做判断;条件为“true”,则执行 一次循环;直到条件测试状态为“false”终止循环
因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:CONDITION为true
退出条件:CONDITION为false
实战训练7
要求:用while实现
1、求100以内所有正整数之和
#!/bin/bashsum=0i=0while [ $i -le 100 ] ;do let sum+=$i let i++ doneecho $sum
2、通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态,统计在线主机和离线主机各多少。
#!/bin/baship=10.1.250.i=1sum=0while [ $i -lt 255 ] ;do if ping -c1 -W1 $ip$i &> /dev/null ;then let sum+=1 echo "$ip$i is up" else echo "$ip$i is down" fi let i+=1doneecho "在线主机$sum台,离线$[255-sum]主机台"
3、打印九九乘法表
#!/bin/bashi=1j=1while [ $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 echodone
4、利用变量RANDOM生成10个随机数字,输出这个10数字 ,并显示其中的最大者和最小者
#!/bin/bashlet i=0,min=max=$RANDOMecho "$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+=1doneecho "最大值是 $max ,最小值是 $min"
5、打印国际象棋棋盘
#!/bin/bashlet x=y=1h=8while [ $x -le $h ];do while [ $y -le $h ];do if [ $[(x+y)%2] -eq 0 ] ;then echo -en "\033[47m \033[0m" else echo -en "\033[40m \033[0m" fi let y+=1 done echolet x+=1,y=1done
#!/bin/bashnum=8for((i=1;i<=$num;i++)){for ((j=1;j<=$num;j++)){ if [ $[(i+j)%2] -eq 0 ];then echo -en "\033[47m \033[0m" else echo -en "\033[42m \033[0m" fi}echo}
6.3
until循环 (和while循环执行条件相反)
until CONDITION; do
循环体
done
进入条件: CONDITION 为false
退出条件: CONDITION 为true
6.4
循环控制语句continue,break
用于循环体中
continue [N]:提前结束第N层的本轮循环,而直接进入下一 轮判断;最内层为第1层
while CONDTIITON1; do CMD1 ... if CONDITION2; then continue fi CMDn ... done
break [N]:提前结束第N层循环,最内层为第1层
while CONDTIITON1; do CMD1 ... if CONDITION2; then break fi CMDn ... done
比如无限循环:
while true; do 循环体 doneuntil false; do 循环体 Done
实战训练8
1、每隔3秒钟到系统上获取已经登录的用户的信息;如果发 现用户hacker登录,则将登录时间和主机记录于日志 /var/log/login.log中,并提示该用户退出系统
#!/bin/bashusername=cent{while true ;do if who | egrep "^\b$username\b" &> /dev/null ;then who | egrep "^\b$username\b" >> /var/log/login.log echo "$username 已经登录" echo "fuck ,go out my system" | write $username else echo "$username 已经下线" fi sleep 3done}
#!/bin/bashusername=hackerexituser(){ echo "fuck you,you will exit,haha" | write $username sleep 2 pidlist=$(ps -f h -u $username | tr -s ' '|cut -d' ' -f2) for i in $pidlist ;do kill -9 $i# echo "正在结束进程" done}while true ;do if w | egrep "^\b$username\b" &> /dev/null ;then w | egrep "^\b$username\b" >> /var/login.log echo "$username 已经登录" exituser else echo "$username 已经下线" fi sleep 3done
2、随机生成10以内的数字,实现猜字游戏,提示比较大或小 ,相等则退出
#!bin/bashlim=10let key=$RANDOM%limread -p "please input a number less than $lim: " numuntil 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,you are very clever" break fi else read -p "error,please input a number less than ten: " num fidone
6.5 一些特殊用法
while循环的特殊用法(遍历文件的每一行):
while read line; do
循环体
done < /PATH/FROM/SOMEFILE
依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
练习 扫描/etc/passwd文件每一行,如发现GECOS字段为空,则填充用户名和单位电话为62985600,并提示该用户的GECOS信息修改成功。
#!/bin/bashphone=" phone number is 62985600"pathname=/etc/passwdwhile read line;do name=`echo $line|cut -d: -f1` b=`echo $line | cut -d: -f5|wc -c` if [ $b -eq 1 ] ;then chfn -f $name -p $phone $name &>/dev/null && echo "$name信息修改成功" || echo "$name信息修改失败" fidone < $pathname
双小括号方法,即((…))格式,也可以用于算术运算
双小括号方法也可以使bash Shell实现C语言风格的变量操作 #I=10 #((I++))
for循环的特殊格式:
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式)) do
循环体
done
控制变量初始化:仅在运行到循环代码段时执行一次
控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算 ,而后再做条件判断
6.6 select 循环与菜单
select variable in list
do
循环体命令
done
select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3提示符等待用户输入
用户输入菜单列表中的某个数字,执行相应的命令
用户输入被保存在内置变量REPLY中
select是个无限循环,因此要记住用break命令退出循环,或用exit命令终止脚本,也可以按Ctrl+c退出循环
select经常和case联合使用
与for循环类似,可以省略in list,此时使用位置参数
比如
#!/bin/bashPS3="please input your chose:"list="start stop restart status exit"select k in $listdo case $k in start) echo start ;; stop) echo stop ;; restart) echo restart ;; status) echo status ;; exit) echo exit ;; *) break ;; esacdone
- linux之基础shell脚本编程2 if语句循环判断
- Linux脚本编程之if判断语句
- Linux shell脚本编程if语句的使用方法(条件判断)
- linux shell脚本编程if语句内判断参数详解
- Linux Shell编程之 for循环语句 if条件语句
- linux shell脚本之if判断
- Linux shell脚本之 if条件判断
- [Linux] shell脚本之if判断
- shell 脚本编程之循环语句
- shell脚本编程之循环语句
- shell编程之循环与判断语句
- shell脚本编程之for语句、if语句使用介绍
- shell脚本之if语句
- shell 脚本之if判断
- Shell脚本编程——(不用判断循环语句)
- Linux脚本(shell)编程(五) if 条件判断
- linux shell编程if语句内判断参数
- linux shell编程if语句内判断参数详解
- 倒计时
- 网易有道2017内推编程题2
- eclipse中提示找不到Httpservlet类
- map+组合数学_____Eureka( POJ 5738 2016多校第二场)
- 微信自定义菜单view类型获取openid访问网页
- linux之基础shell脚本编程2 if语句循环判断
- 03 Button 按钮
- Toggle, Tween(完善篇)
- JDBC (数据库连接)
- Activity生命周期探究
- C++友元理解
- 清晰解题: 寻找最大子数列-Kadane算法
- VC----VS2008LINK : fatal error LNK1000: Internal error during IncrBuildImage
- 轮播