linuxshell循环:for、while、until用法详解

linuxshell循环:for、while、until用法详解

2023年7月10日发(作者:)

linuxshell循环:for、while、until⽤法详解学习脚本就是为了⽅便我们运维⼯作,⽽对运维⼈员从来讲,有很多⼯作也是需要重复执⾏的,⽐如我们管理⽤户帐户时就需要批量创建和删除⽤户帐户。⽽此时如果使⽤系统⾃带的useradd或者userdel去操作的话,就只能机械式的⼀个⼀个创建,⼀个⼀个的删除。那我们是不是就可以考虑写⼀个程序,让它⾃动化的去创建了。此时,我们的循环执⾏概念也就出来了。循环就是让程序按照⼀定的条件反复的执⾏相关操作,直到不在满⾜循环条件时结束。循环语句常见分类:1,for语句2,while语句3,until语句循环体包括两部分:1,循环的进⼊条件2,循环的退出条件循环次数:1,事先已知 for语句2,事先未知 while、until语句for循环常见语法格式:for 变量名 in 列表;do循环体done循环执⾏机制:依次将列表中的元素赋值给变量名,每次赋值后执⾏⼀次循环体,直到列表中的元素耗尽,循环结束列表⽣成⽅式:(1) 直接给出列表(2) 整数列表:(a) {d} 如:{1..10}(b) $(seq [start [step]] end) 如:`seq 1 2 100` 表⽰1-100之间的所有奇数(3) 返回列表的命令 $(COMMAND) 如:`ls /etc`(4) 使⽤glob,如:*.sh(5) 变量引⽤;$@, $*for循环特殊⽤法:双⼩括号⽅法,即((…))格式,也可以⽤于算术运算双⼩括号⽅法也可以使bash Shell实现C语⾔风格的变量操作#I=10#((I++))for循环特殊⽤法格式:for ((控制变量初始化;条件判断表达式;控制变量的修正表达式));do循环体done控制变量初始化:仅在运⾏到循环代码段时执⾏⼀次控制变量的修正表达式:每轮循环结束会先进⾏控制变量修正运算,⽽后再做条件判断for循环应⽤实例:1,计算1-100之间所有正整数的和#!/bin/bash#Author:wangjun#Contact QQ:183530300#Version:1.0#Create time:2016-08-17 16:53:28#Description:1-100 all positive integer's sumdeclare -i sum=0for I in {1..100};do let sum+=$Idoneecho "1-100 all positive integer's sum : $sum"2,⾃动扫描1-254⽹段的所有主机,统计在线主机数与不在线主机数#!/bin/bash

#Author:wangjun#Contact QQ:183530300#Version:1.0#Create time:2016-08-17 11:25:37#Description:ping all hosts and count the numberdeclare -i online=0declare -i offline=0declare -i host=1

for host in `seq 254`;do ping -c 1 -W 1 10.1.250.$host &> /dev/null && echo "10.1.250.$host is online" && let online=$online+1 || let offline++doneecho "Online hosts number : $online"echo "Offline hosts number : $offline"3,⽣成10个随机数,并找出最⼤随机数和最⼩随机数#!/bin/bash#Author:wangjun#Contact QQ:183530300#Version:1.0#Create time:2016-08-17 17:27:45#Description:random number comparativeminrandom=$RANDOMmaxrandom=$minrandomecho $minrandomfor I in {1..9};do RD=$RANDOM echo $RD if [[ $RD -gt $maxrandom ]];then maxrandom=$RD elif [[ $RD -lt $minrandom ]];then minrandom=$RD fidoneecho "Minrandom is : $minrandom"echo "Maxrandom is : $maxrandom"4,打印九九乘法表(第⼀版)#!/bin/bash#Author:wangjun#Contact QQ:18353030#Version:1.0#Create time:2016-08-16 13:07:40#Description:99 multiplication tablefor Row in {1..9};do for Column in `seq $Row`;do echo -ne "${Column}x${Row}=$[$Row*$Column]t" done echodone5,打印九九乘法表(第⼆版)——for循环特殊⽤法#!/bin/bash#Author:wangjun#Contact QQ:183530300#Version:1.0#Create time:2016-08-18 11:35:16#Description:multiplication table

for ((row=1;row<=9;row++));do for ((column=1;column<=$row;column++));do echo -ne "${column}x${row}=$[${column}*${row}]t" done echodone循环执⾏ :将某代码段重复运⾏多次; 重复运⾏多少次: 循环次数事先已知 ;循环次数事先未知 ;有进⼊条件和退出条件。三种循环体:for、while、until。再循环前前介绍步进,在循环中经常⽤到步进。步进显⽰1-10[root@centos6mini app]# echo {1..10}1 2 3 4 5 6 7 8 9 10[root@centos6mini app]# echo $(seq 1 10)1 2 3 4 5 6 7 8 9 101-10 递加[root@centos6mini app]# echo {1..10..2}1 3 5 7 9[root@centos6mini app]# echo $(seq 1 2 10)1 3 5 7 91-10 递减[root@centos6mini app]# echo {10..1..2}10 8 6 4 2[root@centos6mini app]# echo $(seq 10 -2 1)10 8 6 4 21-100间的奇数和偶数[root@centos6mini app]# echo {1..100..2}1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 7779 81 83 85 87 89 91 93 95 97 99[root@centos6mini app]# echo {2..100..2}2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 7880 82 84 86 88 90 92 94 96 98 100[root@centos6mini app]# echo {100..1..2}100 98 96 94 92 90 88 86 84 82 80 78 76 74 72 70 68 66 64 62 60 58 56 54 52 50 48 46 44 42 40 38 36 34 32 30 2826 24 22 20 18 16 14 12 10 8 6 4 2[root@centos6mini app]# echo {99..1..2}99 97 95 93 91 89 87 85 83 81 79 77 75 73 71 69 67 65 63 61 59 57 55 53 51 49 47 45 43 41 39 37 35 33 31 29 2725 23 21 19 17 15 13 11 9 7 5 3 1随机⽣成16位包含数字、⼤⼩写字母、符号的密码cat /dev/urandom |tr -dc '0-9a-zA-Z!@_#?.,' |head -c 16tr -d 和 tr -dc 的⽤法[root@centos6mini app]# echo 12324345 |tr -d 2 #不要数字2134345[root@centos6mini app]# echo 12324345 |tr -dc 2 #⽀取数字222for循环for 变量名 in 列表;do

循环体

done执⾏机制:依次将列表中的元素赋值给“变量名”; 每次赋值后即执 ⾏⼀次循环体; 直到列表中的元素耗尽,循环结束for循环的列表⽣成⽅式:(1) 直接给出列表(2) 整数列表: (a) {d} (b) $(seq [start [step]] end)(3) 返回列表的命令 $(COMMAND)(4) 使⽤glob,如:*.sh(5) 变量引⽤; $@, $*批量创建user1⾄user10,要求设置随机16位密码,包含数字、⼤⼩写字母、符号。并要求⽤户使⽤密码⾸次登录后,强制设置新密码。#!/bin/bash> /root/ i in {1..10};do#创建⼗个⽤户 useradd user$i && echo user$i is created#随机⽣成密码 password=$(cat /dev/urandom |tr -dc '0-9a-zA-Z!@_#?.,' |head -c 16)#将⽤户和密码导出 echo user$i:$password >> /root/#设置密码 echo $password |passwd --stdin user$i &> /dev/null#强制下次登录修改密码 passwd -e user$i &> /dev/nulldone使⽤♥,利⽤for,显⽰出⼀个等腰三⾓形。⽅法⼀:for ((i=1;i<10;i++))do for ((j=1;j<=i;j++))do echo -n "♥" done echodonefor ((i=1;i<9;i++))do for ((j=9;j>i;j--))do echo -n "♥" done echodone♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥⽅法⼆:#!/bin/bash2read -p "请输⼊三⾓形的⾼度: " numfor i in `seq $num`;do for x in `seq 1 $[$num-$i]`;do echo -e " c" done for n in `seq 1 $[2*$i-1]`;do #yanse=`tr -dc '1-6' < /dev/urandom | head -c 1` #echo -e "e[3"$yanse"m♥e[0mc" echo -e "e[34m♥e[0mc" done echo

done ♥

♥♥♥ ♥♥♥♥♥♥♥♥♥♥♥♥⽅法三:#!/bin/bashfor ((i = 1; i < 10; i++))do for ((j = 10; j > i; j--)) do

echo -n " "; done for ((m = 1; m <= i; m++)) do

echo -n "$i " done echo ""done[root@centos7 ~]# ./sjx

1

2 2

3 3 3

4 4 4 4

5 5 5 5 5

6 6 6 6 6 6

7 7 7 7 7 7 7

8 8 8 8 8 8 8 8

9 9 9 9 9 9 9 9 9⽅法四:#!/bin/bash#彩⾊闪烁⼭⾓形read -p "请输⼊三⾓形边长: " wfor (( i=1;i<=$w;i++ )); do for(( j=$w;j>$i;j-- ));do echo -n " " done for (( m=1;m<=i;m++ ));do we=`cat /dev/urandom |tr -dc '1-6' |head -c 1 ` echo -e "033[3"$we";5m♥033[0mc" #红⾊加闪烁 done echodone添加10个⽤户user1-user10,密码为8位随机字符、#!/bin/bash> /root/ i in {1..10};do

useradd user$i && echo user$i is created pass=$(cat /dev/urandom |tr -dc '0-9a-zA-Z!@_#?.,' |head -c 16) #⽣成随机数 echo user$i:---pass:$pass >> /root/ echo $pass |password --stdin user$i &> /dev/nulldone/etc/rc.d/rc3.d⽬录下分别有多个以K开头和以S开头的⽂件;分别读取每个⽂件,以K开头的输出为⽂件加stop,以S开头的输出为⽂件名加start,如K34filename stop S66filename start#!/bin/bashfor i in $(ls /etc/rc.d/rc3.d/);do #查看⽂件内容确定循环次数 if [[ $i =~ ^K.* ]];then echo "$i stop" elif [[ $i =~ ^S.* ]];then echo "$i start" fidone[root@centos6mini app]# ./linshi

K05wdaemon stopK10saslauthd stopK15htcacheclean stopK15httpd stopK30spice-vdagentd stopK50dnsmasq stopK50kdump stopK73winbind 省略...编写脚本,提⽰输⼊正整数n的值,计算1+2+…+n的总和#!/bin/bashread -p "请输⼊⼀个正整数" sw=0if [[ "$s" =~ ^[0-9]+$ ]] ;then for i in $(seq 1 $s) ;do w=$[$w+$i]

done echo "整数1到$s的和为$w"else echo "请输⼊正整数"fi计算100以内所有能被3整除的整数之和⽅法⼀:[root@centos6mini app]# echo {3..100..3} |tr " " "+"|bc #进⾏步进,替换相加1683⽅法⼆:#!/bin/bashfor i in {3..100..3};do #步进,相加 n=$[$n+$i] &> /devnull doneecho $n⽅法三:#!/bin/bashsum=0for n in $(seq 1 100);do i=$[$n/3] #进⾏相除 y=$[3*$i] #进⾏相乘 、运算成功则成⽴ if [ $y -eq $n ];then sum=$[$n+$sum] fidone

echo $sum⽅法四:sum=0for i in {1..100};do if [ $[$i%3] -eq 0 ];then #相除取余进⾏判定 let sum+=$i #进⾏加法运算 fi

doneecho $sum打印九九乘法表for (( i=1 ;i<=9;i++ ));do for ((n=1;n<=9;n++)) ;do w=0 w=$[$n*$i] if [ $n -le $i ];then echo -n " $i*$n=$w " fi doneechodone在/testdir⽬录下创建10个html⽂件,⽂件名格式为数字N(从1到10)加随机8个字母,如:⽅法⼀:#!/bin/bashcd /testdir &> /dev/nullif [ ! $(echo $?) -eq 0 ] ;then #判断⽂件是否存在 mkdir /testdir &> /dev/nullfifor i in $(seq 1 10 );do w=$(cat /dev/urandom |tr -dc '0-9a-zA-Z!@_#?.,' |head -c 8) touch $i$ne⽅法⼆:if ! [ -d /testdir ];then #判断⽂件是否存在 mkdir /testdir &> /dev/null #如果没有创建⽂件fifor i in {1..10};do

touch /testdir/$i`cat /dev/urandom |tr -dc [:alpha:] |head -c 8`.html #创建⽂件done探测局域⽹内的主机172.18.250-254.X能ping通显⽰并保存⾄/root/要求并⾏探测提⾼效率。[root@centos6mini zuoye]# cat

#!/bin/bash> /root/ i in {250..255};do for n in {1..255};do { ping -c1 -w1 172.18."$i"."$n" &> /dev/null if [ $? -eq 0 ] ;then echo "ping 172.18."$i"."$n" is up" #>> /root/ fi }& donedone[root@centos6mini zuoye]# ./

ping 172.18.250.14 is upping 172.18.250.26 is upping 172.18.250.71 is upping 172.18.250.81 is upping 172.18.250.112 is upping 172.18.250.154 is upping 172.18.250.164 is upping 172.18.250.166 is upping 172.18.250.183 is upping 172.18.250.195 is upping 172.18.250.212 is upping 172.18.250.216 is upping 172.18.250.224 is upping 172.18.250.249 is upping 172.18.250.250 is upping 172.18.251.18 is up打印国际象棋棋盘⽅法⼀:[root@centos6mini zuoye]# cat

#!/bin/bashfor n in {1..8};do for i in {1..8} ;do if [ $[$n%2] -eq 0 ];then if [ $[$i%2] -eq 0 ];then echo -e "033[41m 033[0mc" fi if [ $[$i%2] -ne 0 ] ;then echo -e "033[47m 033[0mc"

fi else if [ $[$i%2] -eq 0 ];then echo -e "033[47m 033[0mc" fi if [ $[$i%2] -ne 0 ] ;then echo -e "033[41m 033[0mc"

fi fi done echo

done⽅法⼆:#!/bin/bashfor xline in $(seq 1 8);do #横向 for yline in $(seq 1 8);do #纵向 if [ $[$[$xline+$yline]%2] -eq 0 ];then #判断;横向与纵向相加,最后相除是否等于0 echo -e "033[47m 033[0mc" else echo -e "033[41m 033[0mc" fi done echo

done⽅法三:(放⼤版)#!/bin/bashfor i in {1..8};do for x in {1..4};do #控制单⾏⼤⼩。对已有输出进⾏放⼤ for n in {1..8};do a=`echo $[$[$i+$n]%2]` if [ $a -eq 0 ];then echo -e "e[43m" "" "" "" "" "" "" "" "e[0mc" else echo -e "e[42m" "" "" "" "" "" "" "" "e[0mc" fi done echo donedonewhile循环while CONDITION; do

循环体doneCONDITION:循环控制条件;进⼊循环之前,先做⼀次判 断;每⼀次循环之后会再次做判断;条件为“true”,则执⾏ ⼀次循环;直到条件测试状态为“false”终⽌循环因此:CONDTION⼀般应该有循环控制变量;⽽此变量的值 会在循环体不断地被修正进⼊条件:CONDITION为true退出条件:CONDITION为false“:” 和true的返回值都为真[root@centos6mini zuoye]# true[root@centos6mini zuoye]# echo $?0[root@centos6mini zuoye]# :[root@centos6mini zuoye]# echo $?0判断/var/⽬录下所有⽂件的类型[root@centos6mini app]# cat linshi

#!/bin/bashdc=0lc=0cc=0bc=0oc=0zc=0ls -l /var |grep -v total >/tmp/var_le read linesdo ftype=`echo $lines |awk '{print $1}' |cut -c 1` case $ftype in d) dname=`echo $lines |awk '{print $9}'`; echo "$dname is a Directory" ; let dc+=1;; l) lname=`echo $lines |awk '{print $9}'`; echo "$lname is a Links of Soft " ;let lc+=1 ;; c) cname=`echo $lines |awk '{print $9}'`; echo "$cname is a Character of file" ;let cc+=1;; b) bname=`echo $lines |awk '{print $9}'`; echo "$bname is a Block file" ; let bc+=1;; -) zname=`echo $lines |awk '{print $9}'`; echo "$zname is a common file" ; let zc+=1;; *) echo "Others files"; let oc+=1 esacdone

echo -e "var⽬录下普通⽂件数量: $zcnvar⽬录下⼦⽬录数量:$dcnvar⽬录下链接⽂件数量:$lcnvar⽬录下字符类型⽂件数量: $ccnvar⽬录下块设备⽂件数量:$bcn其他类型⽂件数量:$oc"rm -f /tmp/var_[root@centos6mini app]# ./linshi

cache is a Directorycrash is a Directorycvs is a Directorydb is a Directoryempty is a Directorygames is a Directorygdm is a Directorylib is a Directorylocal is a Directorylock is a Directorylog is a Directorymail is a Links of Soft

nis is a Directoryopt is a Directorypreserve is a Directoryrun is a Directoryspool is a Directorytmp is a Directorywww is a Directoryyp is a Directory-----------------------------var⽬录下普通⽂件数量: 0var⽬录下⼦⽬录数量:19var⽬录下链接⽂件数量:1var⽬录下字符类型⽂件数量: 0var⽬录下块设备⽂件数量:0其他类型⽂件数量:0编写脚本,求100以内所有正奇数之和⽅法⼀:[root@centos6mini zuoye]# echo {1..100..2}1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99[root@centos6mini zuoye]# echo {1..100..2}|tr " " + |bc2500⽅法⼆:[root@centos6mini 3.19]# ./12500[root@centos6mini 3.19]# cat 1#!/bin/bashu=0

for i in {1..100..2}; do let u+=idoneecho $u⽅法三:[root@centos6mini 3.19]# ./12500[root@centos6mini 3.19]# cat 1

#!/bin/bashu=0

i=1while [ $i -le 100 ] ;do let u+=i let i+=2doneecho $u编写脚本,提⽰请输⼊⽹络地址,如192.168.0.0,判断输⼊的⽹段中主机在线状态,并统计在线和离线主机各多少⽅式⼀:#!/bin/bashw=0a=0y=0for (( d=0;d<256;d++ ));do for (( f=1;f<255;f++ ));do { ping -c1 -w1 172.18."$d"."$f" &> /dev/null a=`echo $?` if [ $a -eq 0 ] ; then

echo "172.18."$d"."$f" up" >> /app/ echo "172.18."$d"."$f" up "

fi if [ $a -ne 0 ] ; then

echo "172.18."$d"."$f" down " >> /app/ echo "172.18."$d"."$f" down "

fi }& donedone

w=`cat /app/ |wc -l`echo "通的 : $w"y=`cat /app/ |wc -l`echo "不通的 : $y"rm -rf /app/ -rf /app/⽅式⼆:#!/bin/bashi=1q=1w=0a=0y=0while [ $i -lt 255 ];do while [ $q -lt 255 ];do { ping -c1 -w1 172.18."$i"."$q" &> /dev/null a=`echo $?` if [ $a -eq 0 ] ; then

echo "172.18."$i"."$q" up" >> /app/ echo "172.18."$i"."$q" :up" fi if [ $a -ne 0 ] ; then

echo "172.18."$i"."$q" down " >> /app/

echo "172.18."$i"."$q" down " fi }& let q=q+1

done

let i=i+1 q=1 ####将q的变量值从新赋值为1done

w=`cat /app/ |wc -l`echo "通的主机数为 : $w"y=`cat /app/ |wc -l`echo "不通的主机数为 : $y"rm -rf /app/ /app/编写脚本,打印九九乘法表[root@centos6mini 3.19]# cat 99

#!/bin/bashq=1w=1while [ $q -le 9 ];do while [ $w -le 9 ];do e=0 let e=q*w

if [ $w -le $q ];then echo -n " $w*$q=$e " fi let w+=1 done let q+=1 w=1 echodone[root@centos6mini 3.19]# ./99 1*1=1

1*2=2 2*2=4

1*3=3 2*3=6 3*3=9

1*4=4 2*4=8 3*4=12 4*4=16

1*5=5 2*5=10 3*5=15 4*5=20 5*5=25

1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36

1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49

1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64

1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=814、编写脚本,利⽤变量RANDOM⽣成10个随机数字,输出这个10数字,并显⽰其中的最⼤值和最⼩值[root@centos6mini 3.19]# ./425955257489449最⼤值: 30609最⼩值: 4309[root@centos6mini 3.19]# cat 4

#!/bin/bashq=1while [ $q -le 10 ] ;do echo $[RANDOM] &>> /app/ #echo $[RAND0M] #每次随机都是新的值 let q+=1

donecat /app/=`cat /app/ |sort -rn |tail -n1`e=`cat /app/ |sort -rn | head -n 1`echo "最⼤值: $e"echo "最⼩值: $w"rm -rf /app/5、编写脚本,实现打印国际象棋棋盘[[root@centos6mini 3.19]# cat 5,sh#!/bin/bashq=1w=1while [ $q -le 8 ] ;do while [ $w -le 8 ] ;do if [ $[$[$q+$w]%2] -eq 0 ] ;then ##判断句中的计算需要$[]括起来: echo -e "033[47m 033[0mc" else echo -e "033[41m 033[0mc" fi

let w+=1 done let q+=1 w=1 echodone后续六个字符串:efbaf275cd、4be9c40b8b、44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63是通过对随机数变量RANDOM随机执⾏命令:echo $RANDOM|md5sum|cut –c1-10后的结果,请破解这些字符串对应的RANDOM值⽅法⼀:#!/bin/bash>6while true ;do while true ;do w=`echo $RANDOM ` #定义变量--随机数随时在变化,给他赋值⼀个变量,后边取值就不在变化了 q=`echo $w|md5sum|cut -c1-10` if [ $q == efbaf275cd ] ;then echo "efbaf275cd=$w" #>>6 elif [ $q == 4be9c40b8b ] ;then echo "4be9c40b8b=$w" #>>6 elif [ $q == 44b2395c46 ] ;then echo "44b2395c46=$w" #>>6 elif [ $q == f8c8873ce0 ] ;then echo "f8c8873ce0=$w" #>>6 elif [ $q == b902c16c8b ] ;then echo "b902c16c8b=$w" #>>6 elif [ $q == ad865d2f63 ] ;then echo "ad865d2f63=$w" #>>6 fi donedone[root@centos6mini ~]# cat 6 |sort|uniq44b2395c46=90004be9c40b8b=12000ad865d2f63=1000b902c16c8b=3000efbaf275cd=15000f8c8873ce0=6000⽅法⼆:#!/bin/bashsum=0for i in {1..32767};do num=`echo $i |md5sum | cut -c1-10` case $num in efbaf275cd|4be9c40b8b|44b2395c46|f8c8873ce0|b902c16c8b|ad865d2f63) echo $i let sum++ ;; esac if [ $sum -lt 6 ];then continue else break fidone$#和$*差别[root@centos6mini 3.19]# ./linshi 1 2 2 3 41 2 2 3 42 2 3 42 3 43 44[root@centos6mini 3.19]# cat linshi

#!/bin/bashwhile [ $# -gt 0 ];do

echo $* shiftdone[root@centos6mini 3.19]# ./linshi 1 2 2 3 454321[root@centos6mini 3.19]# cat linshi

#!/bin/bashwhile [ $# -gt 0 ];do

echo $# shiftdone使⽤⼀条命令,依次创建指定的⽤户。如执⾏ tom bob alice harry⽅法1:[root@centos6mini 3.19]# ./linshi tom bob alice harry

⽤户创建成功tom ⽤户创建成功bob ⽤户创建成功alice ⽤户创建成功harry ⽤户创建成功[root@centos6mini 3.19]# cat linshi

#!/bin/bash#!/bin/bashwhile [ $# -gt 0 ]do

id $1 &>/dev/null if [ $? -eq 0 ];then echo $1 is already exsit. shift continue fi useradd $1 echo "$1 ⽤户创建成功" shiftdone删除⽤户[root@centos6mini 3.19]# ./linshi tom bob alice harry

⽤户删除成功tom ⽤户删除成功bob ⽤户删除成功alice ⽤户删除成功harry ⽤户删除成功[root@centos6mini 3.19]# cat linshi

#!/bin/bashwhile [ $# -gt 0 ];do

userdel -r $1 echo "$1 ⽤户删除成功" shiftdone⽅法2:#!/bin/bashwhile [ $# -gt 0 ];do id $1 &> /dev/null && { echo $1 is alread exist && shift && continue; } useradd $1 && echo $1 is created shiftdone每隔3秒钟到系统上获取已经登录的⽤户的信息;如果发现⽤户hacker登录,则将登录时间和主机记录于⽇志/var/log/中,并退出脚本#!/bin/bashwhile true;doif $(ps -au |grep "^hacker.*" &> /dev/null);then #监测前台终端上有没有⽤户登陆信息 echo $(ps -au |grep "^hacker.*" |tr -s " " |cut -d" " -f1,7,9) >> /var/log/ #将⽤户登陆信息保存到⽇志⽂件中/var/log/ break #推出监测else sleep 3s #三秒已监测,防⽌程序太多占⽤cpufidone随机⽣成10以内的数字,实现猜字游戏,提⽰⽐较⼤或⼩,相等则退出[root@centos6mini 3.19]# ./linshi

请输⼊数值 : 1错了 ,⼩了请输⼊数值 : 9错误,⼤了请输⼊数值 : 5猜对了[root@centos6mini 3.19]# cat linshi

#!/bin/bashqe=$( echo $[$RANDOM%10] )

while true ;doread -p "请输⼊数值 : " qw if [ $qw -gt $qe ] ;then echo "错误,⼤了" elif [ $qw -lt $qe ] ;then echo "错了 ,⼩了" elif [ $qe -eq $qw ];then echo "猜对了" break fidone⽤⽂件名做为参数,统计所有参数⽂件的总⾏数[root@centos6mini 3.19]# ./linshi /etc/passwd /etc/sysconfig/network-scripts/ifcfg-eth1 /etc/passwd89[root@centos6mini 3.19]# cat linshi

#!/bin/bashsumhang=0while [ $# -gt 0 ];do hang=$( cat $1 | wc -l ) let sumhang+=hang shiftdoneecho $sumhang4、⽤⼆个以上的数字为参数,显⽰其中的最⼤值和最⼩值⽅法⼀:#!/bin/bashmin=$1 #最⼩值等于第⼀个数值max=$1 #最⼤数等于第⼀个数值while [ $# -gt 0 ];do #进⾏数值数量进⾏判断,做循环 value=$1 #定义变量 if [ $value -gt $max ];then #当第⼆个数⼤于第⼀个数时 max=$value #最⼤值等于后⼀个数值,对max从新赋与新的值 elif [ $value -lt $min ];then #当第⼆个数⼤于第⼀个数时 min=$value #最⼩值等于后⼀个数值 对min从新赋与新的值 fi shift #不管前⾯判断是否成⽴,都进⾏数列左移,doneecho "min $min"echo "max $max"⽅法⼆:#!/bin/bashif [ $# -lt 2 ];then #对输⼊数字数量进⾏检测 echo "type more than two numbers" exit 1fismall=$(echo $* |xargs -n1 |sort -n |head -n 1) #进⾏数值排序big=$(echo $* |xargs -n1 |sort -n |tail -n 1)echo "Maximum number is $big"echo "Minimum number is $small"[root@localhost ~]# echo 1 -3 -99 46 7 32 43 2133 312 |xargs -n1 #以⼀数列进⾏显⽰1-3-9946732432133312read ⽰例:[root@centos6mini 3.19]# while read -p "type your name: " name ;do echo your is $n$name; donetype your name: zhangsanyour is zhangsantype your name: lisiyour is lisitype your name: wangwuyour is wangwutype your name: ^C[root@centos6mini 3.19]# read bing < test。txt[root@centos6mini 3.19]# echo $bing

hello^C[root@centos6mini 3.19]# while read name ; do echo $name ;done # 没有指定输⼊123 #输⼊123 #输出qwe #输⼊qwe #输出asd #输⼊asd #输出zxc #输⼊zxc #输出^C^[[A^C[root@centos6mini 3.19]# while read name ; do echo $name ;done <6 #name为变量,输⼊来⾃⽂件⽂件内容读取完了,循环停⽌helloqweqew12341234asdasadssdasadasdasasdasread ⽰例:显⽰UID⼩于1000的为sys user,⼤于等于1000的为comm user。[root@centos6mini 3.19]# cat linshi

#!/bin/bashwhile read usline ;do #通过read ,定义变量值usline usuid=$( echo $usline |cut -d: -f3 ) ,#引⽤变量usline ,并定义变量usuid usname=$( echo $usline |cut -d: -f1 ) #引⽤变量usline ,并定义变量usname #if [ $usuid -lt 1000 ];then #进⾏判断 if (( $usuid < 1000 )) ;then #进⾏判断(两种⽅式均可以) echo "$usname is a sys user" else

echo "$usname is a comm user" fidone < /etc/passwd #每次循环引⽤⽂件内容⼀⾏,进⾏操作,引⽤完了,循环停⽌。[root@centos6mini 3.19]# ./linshi

root is a sys userbin is a sys userdaemon is a sys useradm is a sys userlp is a sys usersync is a sys usershutdown is a sys userhalt is a sys usermail is a sys useruucp is a sys useroperator is a sys usergames is a sys usergopher is a sys userftp is a sys usernobody is a sys uservcsa is a sys usersaslauth is a sys user找出分区利⽤率⼤于10%的分区,并发出警告/dev/sdaX will be full: 15%要求使⽤while read来实现答案1:#!/bin/bashdf |grep /dev/sd > /app/fenquwhile read line;do used=$(echo $line |tr -s " " % |cut -d% -f5) name=$(echo $line |cut -d" " -f1) if (( $used > 10 ));then echo "$name will be full:$used%" fidone < /app/fenqu[root@centos6mini 3.19]# df |grep /dev/sd >/app/zuoye/3.19/6[root@centos6mini 3.19]# cat /app/zuoye/3.19/6/dev/sda5 28564480 1872060 25234756 7% //dev/sda2 20511356 70276 19392504 1% /app/dev/sda1 194241 31785 152216 18% /boot[root@centos6mini 3.19]# while read line ;do> used=$(echo $line |tr -s " " % |cut -d% -f5)> name=$(echo $line |cut -d" " -f1)> if (( $used > 10 ));then> echo "$name will be full:$used%"> fi> done df_hdf -h | grep ^/dev/[sh]d* >> df_hwhile read disk;do a=`echo $disk |grep -o "<[0-9]{0,3}%" | cut -d% -f1` b=`echo $disk |grep -o "^[^[:space:]]+>"` if [ $a -gt 10 ];then echo "$b will be full: $a%" fi

done < df_h答案3:sed实现#!/bin/bashdf |grep /dev/sd |while read disk;do diskused=$(echo $disk |sed -r 's/.* ([0-9]+)%.*/1/') diskname=$(echo $disk |sed -r 's@(/dev/sd[[:lower:]][[:digit:]]).*@1@') if (( $diskused > 10 ));then echo "$diskname will be full:$diskused%" fidoneuntil循环until CONDITION; do

循环体

done进⼊条件: CONDITION 为false退出条件: CONDITION 为true循环控制语句continue⽤于循环体中continue [N]:提前结束第N层的本轮循环,⽽直接进⼊下⼀ 轮判断;最内层为第1层while CONDTIITON1; do

CMD1 ...

if CONDITION2; then

continue

fi

CMDn循环控制语句break⽤于循环体中break [N]:提前结束第N层循环,最内层为第1层while CONDTIITON1; do

CMD1

...

if CONDITION2; then break

fi

CMDn ...

done循环控制shift命令shift [n]⽤于将参量列表 list 左移指定次数,缺省为左移⼀次。参量列表 list ⼀旦被移动,最左端的那个参数就从列表中删 除。while 循环遍历位置参量列表时,常⽤到 shift./ a b c d e f g h./ a b c d e f g h特殊⽤法1、while循环的特殊⽤法(遍历⽂件的每⼀⾏):while read line; do

循环体done < /PATH/FROM/SOMEFILE依次读取/PATH/FROM/SOMEFILE⽂件中的每⼀⾏,且将 ⾏赋值给变量line2、双⼩括号⽅法,即((…))格式,也可以⽤于算术运算双⼩括号⽅法也可以使bash Shell实现C语⾔风格的变量操作I=10((I++))for循环的特殊格式: for ((控制变量初始化;条件判断表达式;控制变量的修正表达 式))

do

循环体done控制变量初始化:仅在运⾏到循环代码段时执⾏⼀次控制变量的修正表达式:每轮循环结束会先进⾏控制变量修 正运算,⽽后再做条件判断select循环与菜单select variable in list do

循环体命令

doneselect 循环主要⽤于创建菜单,按数字顺序排列的 菜单项将显⽰在标准错误上,并显⽰ PS3 提⽰符, 等待⽤户输⼊

⽤户输⼊菜单列表中的某个数字,执⾏相应的命令

⽤户输⼊被保存在内置变量 REPLY 中select与caseselect 是个⽆限循环,因此要记住⽤ break 命令退 出循环,或⽤ exit 命令终⽌脚本。也可以按 ctrl+c 退出循环

select 经常和 case 联合使⽤与 for 循环类似,可以省略 in list,此时使⽤位置 参量信号捕捉traptrap '触发指令' 信号

⾃定义进程收到系统发出的指定信号后,将执⾏触发指令 ,⽽不会执⾏原操作

trap '' 信号

忽略信号的操作

trap '-' 信号

恢复原信号的操作

trap -p 列出⾃定义信号操作⽂件测试-z string 测试指定字符是否为空,空着真,⾮空为假-n string 测试指定字符串是否为不空,空为假 ⾮空为真 -e FILE 测试⽂件是否存在 -f file 测试⽂件是否为普通⽂件 -dfile 测试指定路径是否为⽬录-r file 测试⽂件对当前⽤户是否可读-w file 测试⽂件对当前⽤户是否可写-x file 测试⽂件对当前⽤户是都可执⾏-z 是否为空 为空则为真 -a 是否不空-u file :是否存在且拥有suid权限

-g file :是否存在且拥有sgid权限

-k file :是否存在且拥有sticky权限[root@centos6mini 3.19]# [ -n "" ]&& echo true #空为假[root@centos6mini 3.19]# [ -n "1" ]&& echo true #⾮空为真true[root@centos6mini 3.19]# [ -n " " ]&& echo true #⾮空为真true[root@centos6mini 3.19]# [ -n ]&& echo true #⾮空为真true[root@centos6mini 3.19]# [ -z ]&& echo true #空为真true[root@centos6mini 3.19]# [ -z "" ]&&echo true #空为真true[root@centos6mini 3.19]# [ -z "1" ] && echo true "#⾮空为假[root@centos6mini 3.19]# [ -z " " ] && echo true #⾮空为假扫描/etc/passwd⽂件每⼀⾏,如发现GECOS字段为空,则填充⽤户名和单位电话为62985600,并提⽰该⽤户的GECOS信息修改成功。#!/bin/bashcat /etc/passwd |while read userline;do #⽤管道实现给循环while赋值 if [ -n "$(echo $userline |cut -d: -f5)" ];then #-n "1" ⾮空为真 continue #为真时啥都不做 else username=$(echo $userline|cut -d: -f1) usermod -c $username-62985600 $username echo $username's gecos already changed! fidone特殊⽤法双⼩括号⽅法,即((…))格式,也可以⽤于算术运算双⼩括号⽅法也可以使bash Shell实现C语⾔风格的变量操作I=10((I++))for循环的特殊格式:for ((控制变量初始化;条件判断表达式;控制变量的修正表达 式))do循环体done控制变量初始化:仅在运⾏到循环代码段时执⾏⼀次控制变量的修正表达式:每轮循环结束会先进⾏控制变量修 正运算,⽽后再做条件判断练习:计算从1加到100的和。#!/bin/bashsum=0for ((i=1;i<=100;i++));do let sum+=idoneecho sum=$sumunset sum i

sum=0i=1while [ $i -le 100 ];do let sum+=i let i++doneecho sum=$sumselect循环与菜单

select variable in listdo循环体命令doneselect 循环主要⽤于创建菜单,按数字顺序排列的 菜单项将显⽰在标准错误上,并显⽰ PS3 提⽰符, 等待⽤户输⼊PS3="Please choose your menu: "⽤户输⼊菜单列表中的某个数字,执⾏相应的命令⽤户输⼊被保存在内置变量 REPLY 中[root@centos6mini 3.19]# ./linshi

1) huangmenji2) huimian3) hulatang4) roujiamoPlease choose your menu: 1The price is $15Please choose your menu: 2The price is $10Please choose your menu: 3The price is $8Please choose your menu: 4The price is $6Please choose your menu: 5get out[root@centos6mini 3.19]# cat ./linshi

#!/bin/bashselect menu in huangmenji huimian hulatang roujiamo;do

case $REPLY in 1) echo "The price is $15";; 2) echo "The price is $10";; 3) echo "The price is $8";; 4) echo "The price is $6";; *) echo "get out";break;; esacdone信号捕捉traptrap '触发指令' 信号⾃定义进程收到系统发出的指定信号后,将执⾏触发指令 ,⽽不会执⾏原操作trap '' 信号 忽略信号的操作rap '-' 信号 恢复原信号的操作trap -p 列出⾃定义信号操作trap 所有可选项[root@centos6mini 3.19]# trap -l

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR111) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+338) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+843) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+1348) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-1253) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-758) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-263) SIGRTMAX-1 64) SIGRTMAX#!/bin/bash

trap 'echo “signal:SIGINT"' int # int 相当与Ctrl+ctrap -p

for((i=0;i<=10;i++))

do

sleep 1echo $i

donetrap '' int #trap '' 信号 忽略信号的操作

trap -p

for((i=11;i<=20;i++)do

sleep 1echo $i

done

trap '-' int #rap '-' 信号 恢复原信号的操作

trap -p

for((i=21;i<=30;i++)do

sleep 1

echo $idone忽略kill -15 ,操作可以成功忽略kill -9操作 ,不成功,⽆法忽略kill -9trap -l,把所有信号打印出来查看kill -9 和kill -15 对应的信号选项select与caseselect 是个⽆限循环,因此要记住⽤ break 命令退 出循环,或⽤ exit 命令终⽌脚本。也可以按 ctrl+c 退出循环select 经常和 case 联合使⽤与 for 循环类似,可以省略 in list,此时使⽤位置

发布者:admin,转转请注明出处:http://www.yc00.com/web/1688986309a191822.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信