Loop and concurrency control of shell

Keywords: Operation & Maintenance MySQL yum vim RPM

Article directory

Cycle and concurrent number control

for while until loop

Grammatical structure

1. =======for loop======================
for condition test
do
    Circulatory body
done
 =======When the condition is true, the loop body is executed=======

2. ======== while loop===================
while condition test
do
    Circulatory body
done
 ========When the condition is true, the loop body is executed=======

3. ======== until loop====================
until condition test
do
    Circulatory body
done
 ========When the condition is false, the loop body is executed=======

for loop concurrent delete user

#!/usr/bin/bash
. /etc/init.d/functions

Prefix=lss

for i in `seq 10`
do
        {
                User=$Prefix$i
                id $User &> /dev/null
                if [ $? -eq 0 ];then
                        userdel -r $User && action "userdel $User" /bin/true
                else
                        echo ""
                        action "NO $User" /bin/false
                fi
        }&              #The middle section is directly executed in the background

done
wait                    #After all the tasks put in the background are completed, the
echo "END"

//Test delete lss1~lss10
[root@mysql-master /soft/scripts]# ./userdel.sh 

NO lss10                                                  [FAILED]
userdel lss6                                               [  OK  ]
userdel lss7                                               [  OK  ]
userdel lss3                                               [  OK  ]
userdel lss4                                               [  OK  ]
userdel lss8                                               [  OK  ]
userdel lss9                                               [  OK  ]
userdel lss1                                               [  OK  ]
userdel lss5                                               [  OK  ]
userdel lss2                                               [  OK  ]
END
[root@mysql-master /soft/scripts]#

for uses a space as a separator when reading a row to get parameters, while uses a row as a separator

// for uses a space as a separator when reading a row to get parameters
//For example: file user.txt
[root@mysql-master /soft/scripts]# cat user1.txt
lss1 123
lss2 1233

lss3    2345

#!/usr/bin/bash
#You want for processing files to be delimited by carriage returns instead of spaces or tab s
#Redefining separator with IFS
#IFS internal field separator
echo "use IFS Before processing"
for line in `cat user1.txt`
do
        user=`echo $line|awk '{print $1}'`
        pass=`echo $line|awk '{print $2}'`
        echo "User:$user Passwd:$pass"
done
echo "use IFS After treatment"
IFS=$'\n'
for line in `cat user1.txt`
do
        user=`echo $line|awk '{print $1}'`
        pass=`echo $line|awk '{print $2}'`
        echo "User:$user Passwd:$pass"
done
[root@mysql-master /soft/scripts]# ./fortest.sh 
//Before handling with IFS
User:lss1 Passwd:
User:123 Passwd:
User:lss2 Passwd:
User:1233 Passwd:
User:lss3 Passwd:
User:2345 Passwd:
//After treatment with IFS
User:lss1 Passwd:123
User:lss2 Passwd:1233
User:lss3 Passwd:2345
[root@mysql-master /soft/scripts]# 

  • while is more suitable for processing files. You can get lines directly
[root@mysql-master /soft/scripts]# vim batch_useradd4.sh 
#!/usr/bin/bash

while read line
do
        User=`echo $line|awk '{print $1}'`
        Password=`echo $line|awk '{print $2}'`
        id $User &>/dev/null
        if [ $? -eq 0 ];then
                echo "$User is already exists or Format error"
        else
                useradd $User && echo "$Password" |passwd --stdin $User &>/dev/null
                if [ $? -eq 0 ];then
                        echo "$User is created"
                fi
        fi
done < /soft/scripts/user1.txt

//test
[root@mysql-master /soft/scripts]# sh batch_useradd4.sh 
lss1 is created
lss2 is created
 is already exists or Format error
lss3 is created
[root@mysql-master /soft/scripts]# 

Concurrency control (FD and named pipeline realize concurrency)

-FD file handle

//Open the file through exec 3 < > ip2.txt
//Close the file through exec 3 < & - release the file handle
//File deletion doesn't matter. As long as the file is not closed and the handle is still there, you can still restore the file cp /proc/$$/fd/6 ip2.txt

//The fd file handle has not been released. It can also be cp back
[root@mysql-master /soft/scripts]# exec 6<> ip2.txt    #Open file
[root@mysql-master /soft/scripts]# cat ip2.txt 
192.168.1.4
...
[root@mysql-master /soft/scripts]# ll /proc/$$/fd
...
lrwx------ 1 root root 64 Oct 28 03:36 6 -> /soft/scripts/ip2.txt
[root@mysql-master /soft/scripts]# rm -f ip2.txt 
[root@mysql-master /soft/scripts]# ll /proc/$$/fd
...
lrwx------ 1 root root 64 Oct 28 03:36 6 -> /soft/scripts/ip2.txt (deleted)

//Recover files by file handle
[root@mysql-master /soft/scripts]# ll /proc/$$/fd
...
lrwx------ 1 root root 64 Oct 28 03:36 6 -> /soft/scripts/ip2.txt (deleted)
[root@mysql-master /soft/scripts]# cp /proc/$$/fd/6 /soft/scripts/ip2.txt
[root@mysql-master /soft/scripts]# cat ip2.txt 
192.168.1.4
...

//close a file handle
[root@mysql-master /soft/scripts]# exec 6<&-    #Close file
[root@mysql-master /soft/scripts]# ll /proc/$$/fd       #File handle released
total 0
lrwx------ 1 root root 64 Oct 28 03:36 0 -> /dev/pts/1
lrwx------ 1 root root 64 Oct 28 03:36 1 -> /dev/pts/1
lrwx------ 1 root root 64 Oct 28 03:36 2 -> /dev/pts/1
lrwx------ 1 root root 64 Oct 28 05:13 255 -> /dev/pts/1
[root@mysql-master /soft/scripts]# 

-Named pipe

//Create named pipes
[root@mysql-master /soft/scripts]# mkfifo /tmp/tmpfifio

//test
//Prepare to accept the command of pipe insertion at terminal 1
[root@mysql-master /soft/scripts]# tty
/dev/pts/1
[root@mysql-master /soft/scripts]# grep yum /tmp/tmpfifio
//Then put the rpm -qa command into the / TMP / tmpffio pipeline at the 0 terminal
[root@mysql-master /soft/scripts]# 
[root@mysql-master /soft/scripts]# tty
/dev/pts/0
[root@mysql-master /soft/scripts]# rpm -qa > /tmp/tmpfifio   #After returning, 1 terminal office can get the command, and finally the pipeline becomes empty

// /dev/pts/1
[root@mysql-master /soft/scripts]# grep yum /tmp/tmpfifio 
yum-plugin-fastestmirror-1.1.31-45.el7.noarch
yum-metadata-parser-1.1.4-10.el7.x86_64
yum-3.4.3-158.el7.centos.noarch
[root@mysql-master /soft/scripts]# 


-Case: FD and named pipeline realize concurrency control

[root@mysql-master /soft/scripts]# vim thread_ping.sh
#Maximum concurrent
Thread_num=5
#Named pipe file
Tmp_fifo=/tmp/$$.fifo

#Create named pipe file
mkfifo $Tmp_fifo
#Open the pipeline file with the file handle (give 6 randomly)
exec 6<> $Tmp_fifo
rm -f $Tmp_fifo

##Control concurrency
for i in `seq $Thread_num`
do
        #Put the maximum concurrent rows into the pipeline for the following read
        echo >&6
done

##
IP=192.168.1

for i in {1..254}
do
        #Read the line through the file handle. When the line is exhausted, stop the next step (concurrent)
        read -u 6
        {
                ping -c1 -W1 $IP.$i &>/dev/null
                if [ $? -eq 0 ];then
                        echo "$IP.$i is UP"
                else
                        echo "$IP.$i is DOWN"
                fi
        #After a concurrent execution, you need to add a blank line to the pipeline for next use
        echo >&6
        }&
done
wait
echo "END"

Posted by solodesignz on Thu, 12 Dec 2019 12:17:44 -0800