for while until loop

Posted by plsanders on Mon, 14 Feb 2022 10:00:17 +0100

for loop

In practical work, we often encounter the situation that a task needs to be executed multiple times, and each time it is executed, only the processing objects are different and other commands are the same. For example, create a system account according to the name list in the address book, and check the survival status of each host according to the server list
When faced with various list repetitive tasks, using simple if statements has been difficult to meet the requirements, and writing all the code in sequence is extremely cumbersome and difficult

for loop statement
1, for loop

1. Grammatical structure

(1) List loop
(2) Loop without list
(3) Class c style for loop
ergodic

for Variable name in { list }
do
command
done
for i in {a..c}
do 
echo $1
done
for i in {1..5}   //Variables are not recognized in {}
do
echo $i
done

for i in 'seq 5'        // seq 5=1, 2, 3, 4, 5 sequence
do
echo $i
done

a=10
for i in `seq $a`  //seq can reference variables
do
echo $i
done

for Variable name in a b c
do
command
done

for Variable name in a b c
do
command
done

for i in a b c  //There is actually no call here, so it is equivalent to looping the following parameters for several times
do
echo 123
done

for i in a b c   //The i variable is called here, so the value of i is displayed normally (a\b\c)
do
echo $i
done

case
Example 1: print the five numbers 1-5

[root@server ~]# vim for.sh

#!/ bin/ bash
for i in {1..5)
do
echo $i
done

Example 2: print hello world five times
Note: Although we defined a variable i, we didn't use it. It just controls the number of cycles

1, What is pandas?

Example: pandas is a NumPy based tool created to solve data analysis tasks.

[root@server ~] # vim for.sh

#!/bin/bash
for i in {1..5}
do
echo hello world
done

Example 3: print abcde

[root@server ~]# vim for.sh 

#!/bin/bash
for i in a b c d e
do
echo $i
done

Example 4: output even numbers within 0-50

[root@server ~]# vim for.sh

#!/ bin/ bash
for i in {0..50..2]   //.. 2 means that the step size is 2, every 2
do
echo $i
done

Application of curly braces {} and seq in for loop:

for i in {1..50..2] 1-50 Odd number of
for i in {2..50..2) 1-50 Even number of

for i in {10..1}1-10 Reverse order
for i in $(seq 10)1-10 Positive order arrangement

for i in $(seq 10 -1 1) 1-10 Reverse order
for i in $(seq 1 2 10)1-10 Odd number of, with step size in the middle

for i in s (seq 0 2 10) 1-10 Even number of, with step size in the middle
for i in $ (seq o 2 10) ; do ;echo $i ;done

The loop without list executes the loop with parameters specified by the user and the number of parameters

for Variable name
do
command
done

Print hello first:

[ root@server ~]# vim for2.sh
#!/bin/ bash
for i
do
echo hello
done
[root&server ~]# ./for2. / / no execution result is passed to sh
[ root@server ~-]# ./for2.sh a / / assign a to variable i. When i has a value, it starts to execute do Done hello

Second:

for i 
do
echo $i
done
[root@client ~] # bash for.sh hello
hello

Class c style for loop

for ( (expr1;expr2;expr3))
do
command
done
expr1:Define variables and assign initial values
expr2:Decide whether to cycle
expr3:Determine how the loop variable changes and when the loop exits

Example 1: print 1-5 iterations:

[zoot@serveE~]# vim for3.sh

#!/bin/bash
for  ((i=1;i<=5;i++))
do
echo $i
done

Note: I + +: i=1 + 1, assign value first, then calculate i=1, and then + 1
++i: 1 + 1 = i operation first, then Assignment 1 + 1, then = i

Example 2: print odd numbers of 1-10

[ root@server ~]# vim for3.sh 

#! /bin/bash
for ( (i=1 ;i<=10;i+=2))  //i=i+2
do
echo $i
done

Attachment 2: Class c style operator usage

++Self variable + 1
– self variable - 1
+=5 self variable + 5
-=5 self variable - 5
=5 self variable 5
/=5self variable / 5
%=5 self variable% 5

Example 3: calculate the odd sum of 1-100

[rooteserver ~]# vim for3.sh

#!/bin/bash
sum=0
for ((i=1;i<=100 ;i+=2))
do
let sum=$i+$sum
done
echo "1-100 The odd sum of is:$sum"

Case:
Example 1: there are two ways to add users in batch
1) Add with suffix batch change

for i in {1..5}
do
useradd stu$i
echo "123" | passwd --stdin stu$i
done

2) Script batch add users

#!/bin/ bash
ULIST=$ (cat / root/users.txt)
for UNAME in $ULIST
do
useradd  $UNAME
echo "123456" | passwd --stdin $UNAME &>/dev/null
done

//Batch delete user's script

vim udelfor.sh
#! /bin/bash
ULIST=$(cat/root/ users.txt)
for UNAME in $ULIST
do
userdel -r $UNAME &>/ dev/ null
done

Example 2: check the host status according to the IP address list
-c number of packets sent- i interval between sending ping packets- W timeout

1) View by text

#!/bin/bash

HLIST=$ (cat /root/ ipadds.txt)
for IP in $HLIST
do
ping -c 3 -i 0.2 -W 3 $IP &> l dev/ null
if [ $? -eq 0 ];then
echo "Host $IP is up."
else
echo "Host $IP is down . "
fi
done

2) View by segment

network="192.168.10"
for addr in { 1..254 }
do
ping -c 2 -i 0.5 -w 3 $network.$addr &> /dev/null
if [ $? -eq 0 ] ;then
echo " $network. $addr is up"
else
echo "$network.$addr is down"
fi
done

#When the user enters the password, the script judges whether the password is correct, prompts the correct information if it is correct, and gives an alarm if it is wrong for 3 consecutive times

vim test. sh
#!/bin/bash
init=123456
for i in {1. .3 }
do
read -p "Please input a password:" pass
if  [ $pass == $init ] ; then
echo "The password is correct"
exit
fi
done
echo"warning:Password error"

#Lucky member

#!/bin/ bash
a=0
b=0
c=0
for ( (i=1;i<=10;i++) )
do
num=$ (expr $ [RANDOM%3+1])
LIST=$(cat /opt/name.txt | grep "$num" | awk -F: '{print $2}')
case $LIST in
zhangsan)
let a++
; ;
lisi)
letb++
;;
*)
let c++
esac
echo "$LIST"
done
echo "zhangsan : $a Times lisi:$b Times dangwu : $c second"

while Loop

1. Grammatical structure
2. Dead cycle
(1) Grammatical structure (3 kinds)

The while loop is generally used for conditional judgment. If the judgment condition is true, it enters the loop. When the condition is false, it jumps out of the loop

1. Grammatical structure

while expression
do
    command
done

Example 1: print 1-5

[root@server ~]# vim while.sh
#!/bin/bash
i=1
while [ $i -le 5 ]
do
    echo $i
    let i++   //Note that if the value of $i is not changed here, it will become an endless loop
#i=$[$i+1] / / two ways of writing
done
echo "last i The value of is: $i"

Example 2: output a number between 1 and 100 that cannot be divided by 3

[root@server myscripts]# vim 3.sh 
#!/bin/bash
i=1
while [ $i -le 100 ]
 do
 if [[ $i%3 -ne 0 ]]
 then echo "$i"
 fi
 let i++
done

Example 3: print the sum of 1-100

#!/bin/bash
i=1
sum=0
while [ $i -le 100 ]
do
        let sum=$i+$sum
        let i++
done
echo $sum

Example 4: monitoring the running status of a service (httpd)

while ps aux | grep httpd | grep -v grep &> /dev/null
do
echo "httpd Running"
sleep 2
done
echo "httpd Not running"

while loop

while [ 1 -eq 1 ]  //Write an expression that is always true. The condition that 1 equals 1 is always true, so the script will continue to loop
do
    command
done

while true
do
    command
done

while true
do
    command
done

while :
do
    command
done

Example 1: guess the number. If you don't guess correctly, keep guessing=========

num=10
while true
do
read -p "Please enter a number:" shu
if [ $shu -eq $num ];then
        echo "Bingo"
        break
elif [ $shu -gt $num ];then
        echo "Guess it's too big"
elif [ $shu -lt $num ];then
        echo "Guess it's small"
fi
done

Example 2
1. Users who add regular numbers in batch========

#!/bin/bash
USERS="stu"
i=1
while [ $i -le 20 ] 
do
useradd ${USERS}$i
echo "123456" | passwd --stdin ${USERS}$i &> /dev/null 
let i++
done

Example 3
Guess commodity price game
$random is used to generate random numbers from 0 to 32767

The first method

#!/bin/bash
PRICE=$(expr $RANDOM % 1000)
a=0
echo "The actual price range of goods is 0-999,Guess how many?" 
while true
do
read -p "Please enter the price you guessed:" n 
let a++
if [ $n -eq $PRICE ] ; then
echo "Congratulations on your correct answer,The actual price is $PRICE" 
echo "How long have you guessed $a second"
exit 0
elif [ $n -gt $PRICE ] ; then
 echo "Your guess is high!"
else
echo "Guess it's low!"
fi 
done

The second method

#!/bin/bash
sorce=$[$RANDOM % 1000]
a=1
num=0
while[ $a -lt 2 ]
do
read -p "Please enter the price you guessed(1-999 between) :"  price
if [ $price -eq $sorce ] ; then
echo "Congratulations, you guessed right!"
let num++
let a++
elif [ $price -gt $sorce ] ; then
echo "Your guess is high!"
let num++
elif[ $price -lt $sorce ] ; then
echo "Guess it's small!"
let num++
fi
done
echo "You guessed $num second!"

Example 4: monitor the local memory and the remaining space of the hard disk in real time. When the remaining memory is less than 500M and the remaining space of the root partition is less than 1000M, send an alarm email to the root administrator

#!/bin/bash
#Extract the remaining space of the root partition
disk_size=$(df / |awk '/\//{print $4}')
#Extract remaining memory space
mem_size=$(free |awk '/Mem/{print $4}') 
while :
do
#Note that the amount of space extracted from memory and disk is in Kb
if [ $disk_size ‐le 512000 -a $mem_size ‐le 1024000 ];then 
mail ‐s Warning root <<EOF
Insufficient resources,Insufficient resources EOF
fi 
done

Example 5 define network card traffic

#!/bin/bash
#Define flow units
DW=kb/s
while :
do
    #Define the extracted network card traffic value at a certain time point. The network card here is ens33
    OLD_IN=$(cat /proc/net/dev | awk '$1~/ens33/{print $2}')
    OLD_OUT=`cat /proc/net/dev | awk '$1~/ens33/{print $10}'`
    sleep 5

#Define the extracted network card traffic value at the next time point.
NEW_IN=$(cat /proc/net/dev | awk '$1~/ens33/{print $2}')
NEW_OUT=`cat /proc/net/dev | awk '$1~/ens33/{print $10}'`
 
#Calculate the traffic. The default is Bytes, which is converted to kb/s
IN=$[$[$NEW_IN - $OLD_IN]/1024]$DW
OUT=$[$[$NEW_OUT - $OLD_OUT]/1024]$DW
sleep 5
 
#Print corresponding values
echo -e "Receive data: ${IN}\t Send data: $OUT"

#!/bin/bash
i=1
sum=0
while [ $i -le 5 ]
do
  echo "Enter the second $i Store"
  read -p "Whether to enter(yes/no)" doing
  while [ $doing = "yes" ]
    do
       echo "1:clothes¥200"
       echo "2:shoes¥150"
       echo "3:glove¥40"
       echo "4:trousers¥155"
       read -p "Please select the product sequence you need to purchase:" num
       case $num in
           1)
             echo "Clothes purchased successfully"
             expr $[sum+=200] &> /dev/null
           ;;
           2)
             echo "Shoes purchased successfully"
             expr $[sum+=150] &> /dev/null
           ;;
           3)
             echo "Gloves purchased successfully"
             expr $[sum+=40] &> /dev/null
           ;;
           *)
             echo "Pants purchased successfully"
             expr $[sum+=155] &> /dev/null
      esac
      read -p "Continue to purchase(yes/no)" doing
      
   done
   let i++
   if [ $doing = "no" ]
     then
     continue
   fi
done
   echo "Total purchase price:$sum"

until loop

Contrary to while, the condition is false to enter the loop, and the condition is true to exit the loop
Grammatical structure

until expression
do
    command
done

Example 1: calculate 1-50 and 1275

First kind

#!/bin/bash
i=0;s=0
until [ $i -eq 51 ] 
do
let s+=i    #s+=i, equivalent to s=s+i, using plus assignment
let i++    
done
echo $s

Second

vim 50.sh
#!/bin/bash
i=1
sum=0
until [ $i -eq 51 ]   //Note here that if it is 50, the condition is true. At the end of the loop, it calculates the sum of 1-49, and until [$I - GT 50] is also OK
  do
  sum=$[$i+$sum]
  let i++
  done
echo "$sum"

Dead cycle structure

until false
do
    command
done

until [ 1 -ne 1 ]
do
    command
done

Case 2: log in to zhangsan and send a message to zhangsan using root================

#!/bin/bash
username=$1
#Judgment information format
if [ $# -lt 1 ];then
  echo "Usage:`basename $0` <username> [<message>]" 
  exit 1
fi
#Determine whether the user exists
if grep "^$username:" /etc/passwd >/dev/null ;then : 
else
   echo "user does not exist"
   exit 1
fi
#Whether the user is online. If not, contact once every 5 seconds
until who|grep "$username" >/dev/null
do
	echo "user does not exist"
        sleep 5
done
mes=$* 
echo $mes | write $username
 Note: switch users during test

Loop control statement

The for loop is generally executed together with conditional judgment statements and process control statements, so it is necessary to skip the loop and abort the loop. There are three commands to control the loop

1,continue
Continue, but the following code in the loop body will not be executed. Start to restart the next loop

Example 1: print numbers 1-5, and 3 does not print

[root@server ~]# vim for4.sh

#!/bin/bash
for ((i=1;i<=5;i++))
do
        if [ $i -eq 3 ];then
        continue
        else
        echo $i
        fi
done

As a result, 1245 and 3 will not be output, because the following echo statement will jump out to execute the next cycle

2,break
Interrupt, stop the circulation immediately and execute the code outside the circulation

Example 2: the numbers from 1 to 10 are not printed after 7

[root@server ~]# vim for4.sh

#!/bin/bash
for ((i=1;i<=10;i++))
do
        if [ $i -eq 8 ];then
        break
        else
        echo $i
        fi
done

3,exit
Directly jump out of the program, followed by the status return code, such as exit 1, etc

for i in {1..5}
do
if [ $i -eq 3 ];then
        exit  100 
else
        echo $i
fi

done
echo hi

Jump out of the program directly, so the last echo hi will not be executed, and the return code is 100 through $? see

Topics: shell