Circular statements of shell script (for, while, until)

Posted by nightdesigns on Tue, 08 Feb 2022 19:18:32 +0100

1, for loop statement

1. Grammatical structure:
(1) List loop
(2) Loop without list
(3) Class C style for loop

Format:

for  Variable name  in  Value list
do
	Command sequence
done

2. Usage:

Read different variable values to execute the same set of commands one by one

for loops are often used in scenarios where you already know how many cycles to cycle

Example 1: display numbers from 0 to 9

Method 1:
#!/bin/bash 

for i in {0..9}
do
        echo $i
done


Method 2:
#!/bin/bash 

for i in $(seq 0 9)
do
        echo $i
done

Example 2: print hello world five times

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

Example 3: odd sum between 1 and 10

#/bin/bash
sum=0
for i in {1..10..2}
do
  sum=$[sum+i]
  let i++
done
echo "10 The odd sum within is: $sum"

Example 4: output an even number between 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

Tips: 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 steps in the middle

When the loop without list is executed, it is determined by the parameters specified by the user and the number of parameters

Format:
for Variable name
do
command
done

Example: print hello world

[ root@server ~]# vim k.sh
#!/bin/ bash
for i
do
echo hello world
done
[root&server ~]# sh k.sh     ###No parameters were passed to the script, so it was executed without results
[ root@server ~-]# sh k.sh a     ###Assign a to variable i, and when i has a value, it starts to execute do Done
hello world

Second:

for i 
do
echo $i
done
[root@localhost ~]# sh k.sh helloworld
helloworld

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: print 1-5 iterations

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

[root@localhost ~]# sh k.sh 
1
2
3
4
5

notes: 
i++ :  i=1+1  Assignment before operation  i=1  Later +1

++i :  1+1=i  Operation first and then Assignment 1+1  Later =i

Example 2: print odd numbers of 1-10

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


[root@localhost ~]# sh k.sh 
1
3
5
7
9

Attachment: Class c style operator usage

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

Example 3: calculate the odd sum of 1-100

#!/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"

Other cases:

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

#!/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 &> /dev/null
if [ $? -eq 0 ];then
echo "Host $IP is up."
else
echo "Host $IP is down . "
fi
done

2) View by segment

#!/bin/bash
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

#!/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"

2, while loop statement

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

Usage:

Test a condition repeatedly, and execute it repeatedly as long as the condition is true

Often established when the scope is not known

Format:

while Conditional test operation
do
	Command sequence
done

Example 1: print 1-5

#!/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

#!/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

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 :
do
    command
done

Example: guessing numbers games

#!/bin/bash
 
pc_num=$[RANDOM%3+1]
count=0
while true
do 
   read -p "Please enter a number:" user_num
   if [ $user_num -eq $pc_num ]
   then 
      echo "That's right"
      break
   elif [ $user_num -gt $pc_num ]
   then
      echo "Your number is too big"
   else
      echo "Your number is too small"
   fi
   let count++
done
   echo The number of times you enter is: $count

Example 2: guessing commodity prices
$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 "You guessed all together $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 3: 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 4: 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"

3, until loop statement

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

Usage: test a condition repeatedly, and execute it repeatedly as long as the condition is not tenable

Format:

until Conditional test operation
do
 Command sequence
done

Example 1: calculate the sum of 1 to 100

#!/bin/bash
sum=0
i=0
until [ $i -gt 100 ]
do
 sum=$[sum+i]
 let i++
done
echo "{1..100}And: $sum"

Dead cycle structure

until false
do
    command
done

until [ 1 -ne 1 ]
do
    command
done

Case: log in to zhangsan and use root to send messages to zhangsan

#!/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

4, 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

For example: print numbers from 1 to 5, and 3 does not print

#!/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: the numbers from 1 to 10 and those after 7 are not printed

#!/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 $i

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

5, Summary

1. Structure of for statement
2. Structure of while statement
3. Structure of until statement
4. Loop control statement

Topics: Linux