Detailed explanation of for loop usage in shell

Posted by Ozzapoo on Fri, 17 Sep 2021 09:24:07 +0200

for command:
Various uses of for i in:

  • for i in "file1" "file2" "file3"
  • for i in /boot/*
  • for i in /etc/*.conf
  • for i in $(seq -w 10) -- equal width 01-10
  • for i in {1...10}
  • for i in $( ls )
  • for I in $(< file)
  • for i in "$@" -- take all location parameters, which can be abbreviated as for i
    Note: the bash shell supports C-type for loops
#!/bin/bash
j=$1
for ((i=1; i<=j; i++))
do
touch file$i && echo file $i is ok
done

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • $@: contents of all location variables
  • $#: number of location variables
  • $0: file name
  • $*: contents of all location variables

Precautions for script writing:

  1. Specify what shell to use at the beginning, such as bash, ksh, csh, etc
  2. Script function description, usage, author, version, date, etc
  3. The variable name and function name should have practical meaning. The function name should be in the form of gerund, and the first letter of the second word should be capitalized. For example: updateConfig()
  4. Indent with 4 spaces instead of TAB
  5. Use braces to get the variable value, such as ${varname}
  6. When deleting files, if there are variables in the path, judge whether the variables have values, such as rm -f ${abc} / * if the variable abc has no value, the files in the root directory will be deleted
  7. Try not to use cd to change directories in scripts
  8. Function description, usage, version, date, etc. shall also be included in the function
  9. The function should be single and not too complex
  10. $() is better than ` `
  11. Try not to use multiple if statements, but instead use case statements instead
  12. If you need to execute a certain number of loops, you should replace the while statement with the for statement
  13. The input parameters shall be judged correctly
  14. Add more notes to facilitate reading by yourself or others.

Exercise 1: script to empty all arp cache records:

#!/bin/bash
for i in $(arp | tail -n +2|tr -s ' ' |cut -d' ' -f1)
do
    arp -d $i
done

   
  • 1
  • 2
  • 3
  • 4
  • 5

Exercise 2: generate ten random numbers:
Method 1:

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

   
  • 1

Method 2:

for i in $(seq 10);do echo $RANDOM;done

   
  • 1

Exercise 3: count down to five seconds:

#!/bin/bash
echo "Ready to count down to 5 seconds:"
for i in $(seq 5 -1 1)
do
    echo -en "$i";sleep 1
done
echo -e "start"

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Method 2:

#!/bin/bash
echo "Ready to count down to 5 seconds:"
for i in $(seq 5 -1 1)
do
    echo -en "\b$i";sleep 1
done
echo -e "\b start"

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Exercise 4: batch adding users:

#!/bin/bash
for i in $(cat /root/users.txt)        -->Read file name from list file
do
    useradd $i
    echo "123456" | passwd --stdin $i -->Specify password string through pipeline
done

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

practice:
Find out users with uid greater than 10000 and delete them. You must use the for loop.

#/bin/bash
u_uid=(`cat /etc/passwd | awk -F: '{print $3}'`)
u_name=(`cat /etc/passwd | awk -F: '{print $1}'`)
for i in  `seq ${#u_uid[@] }`
do
    if ((  ${u_uid[i-1]} > 10000  ))
    then
           userdel -r  ${u_name[i-1]}&&echo "${u_name[i-1]} delete ok"
    fi
done

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Method 2: find users greater than 10000 with regular:

cat /etc/passwd | egrep "1[0-9]{4} | [2-9]{5,}"

   
  • 1

Example: check the ip address of the surviving host in the network according to the ip address.

break statement: (jump out of loop)

  • In loop statements such as for, while and until, it is used to jump out of the current loop body and execute the statement after the loop body

continue statement: (jump out of this cycle)

  • In loop statements such as for, while and until, it is used to jump out of the remaining statements in the loop body and re judge the conditions in order to execute the next loop.

Exercise: batch adding users using the for loop

#!/bin/bash
for i in $(cat /root/users.txt) -->Read file name from list file
do   
    useradd $i
    echo "123456"| passwd $i --stdin   -->Specify password through pipeline UNAME
done

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(ps: judge whether the user has an id command)

Position variable

  • Location variable: $n, but location parameters greater than 9 should be enclosed by {}:
  • The function of location variable: in fact, it is to pass parameters to the script
  • $0 -- "represents the script's own name

(the most common usage of location variable: bash 1.sh variable 1 variable 2...)

Predefined variables:

  • $#: number of location variables on the command line
  • $*: contents of all location variables (less used)
  • $@: contents of all location variables
  • $0: name of currently executing process / program
  • : PID value of current shell, echo: PID value of current shell, echo
    ; ps $$, commonly used as a suffix for temporary variables
  • $?: The status returned after the execution of the previous command. When the returned status value is 0, it indicates normal execution, and a non-0 value indicates abnormal execution or error
  • $RANDOM: RANDOM number, which can be used as temporary file name

Example: output random numbers within 0-9 – "echo $((RANDOM%10))
Output random numbers within 1-10 – "echo $((RANDOM%10+1))

  • !$: Represents the parameters of the previous command
  • !!: Execute the previous command

Exercise: Exporting
$1 is aa,
$2 is bb,
$3 is cc,
$4 is dd,
$5 is ee
answer:

#!/bin/bash
echo "there are $# arguments in this scripts"
N=1  -->variable N Used to count  
for i in $@
do
    echo "\$$N is $i"
    ((N++))
done

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

PS:
ping command

  • -c 1 - "ping only once.
  • -i 0.2 – the interval between the first package and the second package is 0.2s
  • -w 2 -- wait for 2s only

Example:
ping 172.30.132.123 &>/dev/null
Redirection is useless for ping command. Successful execution $? It returns 0, or 1 if it is unsuccessful

Check the surviving host IP in the network according to the IP address (large-scale scanning)

#!/bin/bash
for r in 192.168.1.{1..254}
do
    ping -c1 -w1 "${ip}" &>/dev/null
done
arp -n|grep ether|tr -s ' '|cut -d' ' -f1

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

One of the most classic scripts for the ping command:

for i in {1..193}
do
    ( ping -c1 -i0.2 -w1 172.16.30.$i &>/dev/null
    if ((  $?==0  ))
    then
            echo "172.16.30.$i up"    >>2.txt
    else
            echo "172.16.30.$i down"    >>3.txt
    fi )&    -->In this way, this paragraph is put into the background for execution, which greatly speeds up the speed.
done
sleep 2
live_pc_num=`cat 2.txt|wc -l`
down_pc_num=`cat 3.txt|wc -l`
echo "there are $down_pc_num is down"
echo "there are $live_pc_num is up"
echo "list:"
cat 2.txt
rm -rf 2.txt 3.txt

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

break statement
Typical while loop:

#!/bin/bash
i=1
while :    -->:Equivalent to true
do
        echo "$i"
        ((i++))
        sleep 0.3
done
 Note: This is an endless loop and will be executed all the time

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

With break, you can jump out of the loop:

#!/bin/bash
i=1
while :
do
        echo "$i"
        ((  i++  ))
        if ((   i==20000  ))  -->Only 1 is output-19999
        then
                break
        fi
done

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Summary

  • break: jump out of the whole loop
  • exit: jump out of script
  • continue: jump out of this loop and execute the next loop

Case exercise 9:
Add users in batch and meet the following requirements:

answer:

#!/bin/bash
read -p "Please enter the prefix of the user name:" a 
read -p "Please enter the number of users:" num
if (( $num<=10 ))
then
        n=0
        for i in `seq $num`
        do
               if useradd $a$i &>/dev/null
                then
                        echo "user $a$i Created successfully!"
                        (( n++ ))
                        echo "123456"|passwd $a$i --stdin &>/dev/null
                fi
        done
        echo "Total number of users created: $n individual"
else
        echo "You can only create 10 users at most!"
fi

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Original link: https://blog.csdn.net/qq_18312025/article/details/78278989

Topics: shell securecrt