This article mainly introduces examples of shell programming
First, the logical judgment if statement 1. Judging the age?
[[email protected] 9_1] #cat iftest.sh
#! / bin / bash
read -p "Please input your age:" age
## Judge that the user input must be a number
if [["$ age" = ~ ^ [0-9] + $]]; then
true
else
echo "Please input digit"
exit 10
fi
## Determine the age of the user and output the corresponding information
if ["$ age" -ge 0 -a $ age -le 18]; then
echo "good good study, day day up"
elif ["$ age" -gt 18 -a $ age -le 60]; then
## Since it has been judged to be a number and a positive integer, "$ age" -gt 18 can be omitted;
echo "work hard"
elif ["$ age" -gt 60 -a $ age -le 120]; then
## Similarly, here "$ age" -gt 60 can also be omitted, optimized
echo "enjoy your life"
else
echo "you don not come from the earch"
fi
2. How to judge yes or no?
Idea 1:
1. All choices entered by the user: y | yes | Y | YES, same as n | no | N | NO
2. Unified judgment is uppercase or lowercase: tr to convert
3. Use two choices to judge: 2: Use regular matching y | yes; n | no or uppercase
#! / bin / bash
read -p "Input yes or no:" answer
ans = `echo" $ answer "| tr‘ A-Z ’‘ a-z’`
if ["$ ans" = "yes" -o "$ ans" = "y"]; then
echo "YES"
elif ["$ ans" = "no" -o "$ ans" = "n"]; then
echo "NO"
else
echo "Please input yes or no"
fi
Idea 2: Use regular to judge
#! / bin / bash
read -p "Input yes or no:" answer
if [["$ answer" = ~ ^ [Yy] ([Ee] [Ss])? $]]; then
echo YES
elif [["$ answer" = ~ ^ [Nn] [Oo]? $]]; then
echo "NO"
else
echo "Please input yes or no"
fi
4. Determine whether you are rich or handsome?
[[email protected] 9_1] #vim yesorno2.sh
#! / bin / bash
read -p "Are you rich? yes or no:" answer
if [["$ answer" = ~ ^ [Yy] ([Ee] [Ss])? $]]; then
echo OK
elif [["$ answer" = ~ ^ [Nn] [Oo]? $]]; then
read -p "Are you handsome? yes or no:" answer
if [["$ answer" = ~ ^ [Yy] ([Ee] [Ss])? $]]; then
echo Ok
exit
elif [["$ answer" = ~ ^ [Nn] [Oo]? $]]; then
echo "work hard"
else
echo "Please input yes or no"
fi
else
echo "Please input yes or no"
fi
Second, the case statement of logical judgment 1. Judgment of numbers
[[email protected] 9_1] #vim casetest.sh
#! / bin / bash
read -p "Please input a digit:" num
case $ num in
1 | 2 | 3)
echo 1,2,3
;;
4 | 5 | 6)
echo 4,5,6
;;
7 | 8 | 9)
echo 7,8,9
;;
*)
echo other digit
;;
esac
2. Judge yes | no
#! / bin / bash
read -p "Please input yes or no:" ans
case $ ans in
[Yy] | [Yy] [Ee] [Ss])
echo YES
;;
[Nn] | [Nn] [Oo])
echo NO
;;
*)
echo input false
;;
esac
3. Print menu:
[[email protected] ~] #cat menu.sh
#! / bin / bash
cat << EOF
1: lamian
2: huimian
3: daoxiaomian
4: junbing
5: mifan
EOF
read -p "Please choose the number:" num
case $ num in
1)
echo "lamian price is 15"
;;
2)
echo "huimian price is 18"
;;
3)
echo "daoxiaomian price is 13"
;;
4)
echo "junbing price is 10"
;;
5)
echo "mifan price is 2"
;;
*)
echo "INPUT false"
esac
effect:
[[email protected] ~] #sh menu.sh
1: lamian
2: huimian
3: daoxiaomian
4: junbing
5: mifan
Please choose the number: 5
mifan price is 2
Third, the loop for loop
help for-two kinds of syntax
Syntax 1:
for NAME [in WORDS ...]; do COMMANDS; done
Syntax 2:
for ((: for ((exp1; exp2; exp3)); do COMMANDS; done
[[email protected] 9_2] #for num in 1 2 3 4 5; do echo "num = $ num"; done
num = 1
num = 2
num = 3
num = 4
num = 5
1. Continue to add sums
[[email protected] 9_2] # sum = 0; for num in 1 2 3 4 5; do sum = $ [sum + num]; done; echo sum = $ sum
sum = 15
2. Find the sum of 1 + 2 + 3 + .. + 100 (Interview questions)
Method 1: {1..100} Generate sequence
[[email protected] 9_2] # sum = 0; for num in {1..100}; do sum = $ [sum + num]; done; echo sum = $ sum
sum = 5050
## The methods used for calculation are $ [] and $ (()), let, and so on.
Method 2: seq 100 generates sequence
[[email protected] 9_2] # sum = 0; for num in `seq 100`; do sum = $ [sum + num]; done; echo sum = $ sum
sum = 5050
2.1 Find the sum of all odd numbers within 1 + 2 + 3 + .. + 100 | the sum of all even numbers?
Sum of odd numbers:
[[email protected] ~] # sum = 0; for num in {1..100..2}; do sum = $ [sum + num]; done; echo sum = $ sum
sum = 2500
[[email protected] ~] # sum = 0; for num in `seq 1 2 100`; do sum = $ [sum + num]; done; echo sum = $ sum
sum = 2500
Sum of even numbers:
[[email protected] ~] # sum = 0; for num in {2..100..2}; do sum = $ [sum + num]; done; echo sum = $ sum
sum = 2550
[[email protected] ~] # sum = 0; for num in `seq 2 2 100`; do sum = $ [sum + num]; done; echo sum = $ sum
sum = 2550
2.2 How to print odd and even numbers?
[[email protected] 9_2] #seq 1 2 10 ———— Print odd number
1
3
5
7
9
[[email protected] 9_2] #seq 2 2 10 ———— Print even number
2
4
6
8
10
[[email protected] 9_2] #seq 1 10 | sed -n "1 ~ 2p" —————— sed print odd number
1
3
5
7
9
[[email protected] 9_2] #seq 1 10 | sed -n "2 ~ 2p" ———————— sed print even number
2
4
6
8
10
[[email protected] ~] #echo {1..10..2} ———————————————— {} can also output odd
1 3 5 7 9
[[email protected] ~] #echo {2..10..2} ———————————————— {} Print even number
2 4 6 8 10
3. Exercise: How to batch execute all scripts in a directory? ———— (Prerequisite: All files have x permissions and are non-interactive)
[[email protected] 9_2] #ls
case_yesorno.sh test.sh
[[email protected] 9_2] #
[[email protected] 9_2] #for filename in * .sh; do ./$filename;done
Please input yes or no: yes
YES
hello, world
4. Exercise: Create user1..10 users in batches and set the password to magedu. Set the first login to change the password?
[[email protected] 9_2] #vim createuser_n.sh
#! / bin / bash
for num in {1..10}; do
useradd user $ {num}
echo "magedu" | passwd --stdin user $ {num} &> / dev / null
passwd -e user $ {num} &> / dev / null
done
5. Exercise: Write a XX scanner to scan a network segment (1-254). Which hosts are turned on?
## The default is sequential execution. After ping one ip and then ping the next, can it be executed in parallel?
[[email protected] 9_2] #cat scanip.sh
#! / bin / bash
## Empty the file before each execution
> /data/iplist.log
net = 172.20.129
for i in {1..254}; do
## Add {} to achieve parallel execution
{if ping -c1 -W1 $ net. $ i &> / dev / null; then
echo $ net. $ i is up
echo $ net. $ i >> /data/iplist.log ## Note that this is an append, so empty the file at the beginning of the script
else
echo $ net. $ i is down
fi} & ## correspond back and forth, and put into the background to execute
done
wait ## Because you need to manually press enter to exit, add the wait command to automatically exit
Optimized version: interactive input
[[email protected] 9_2] #vim scanip.sh
#! / bin / bash
> /data/iplist.log
## Interactive input
read -p "Please input the network: (eg: 192.168.0.0):" net
## Intercept the first three paragraphs, otherwise 1.1.1.0.249
net = `echo $ net | cut -d. -f1-3`
for i in {1..254}; do
{if ping -c1 -W1 $ net. $ i &> / dev / null; then
echo $ net. $ i is up
echo $ net. $ i >> /data/iplist.log
else
echo $ net. $ i is down
fi} &
done
wait
6. Exercise: Write a netid.sh that calculates the network ID, ip address and subnet mask to do AND operation, as shown below:
[[email protected] 9_2] #echo $ [193 & 240]
192
[[email protected] 9_2] #cat netid.sh
#! / bin / bash
read -p "input a ip:" ip
read -p "input a netmask:" netmask
## One field per cut, and then loop 4 times
for i in {1..4}; do
net = `echo $ ip | cut -d. -f $ i`
mask = `echo $ netmask | cut -d. -f $ i`
if [$ i -eq 1]; then
## The first field is combined with the other field, and finally combined
netid = $ [net & mask]
else
netid = $ netid. $ [net & mask]
fi
done
echo netid = $ netid
Optimized version:
[[email protected] 9_2] #cat netid.sh
#! / bin / bash
read -p "input a ip:" ip
read -p "input a netmask:" netmask
for i in {1..4}; do
net = `echo $ ip | cut -d. -f $ i`
mask = `echo $ netmask | cut -d. -f $ i`
subnetid = $ [net & mask]
if [$ i -eq 1]; then
netid = $ subnetid
else
netid = $ netid. $ subnetid
fi
done
echo netid = $ netid
Other references:
[[email protected] 9_2] #cat netid1.sh
#! / bin / bash
read -p "input a ip:" ip
read -p "input a netmask:" netmask
for ((i = 1; i <5; i ++)); do
ip1 = `echo $ ip | cut -d. -f $ i`
netmask1 = `echo $ netmask | cut -d. -f $ i`
echo -n $ [$ ip1 & $ netmask1] ## Use -n to append without newline
if [$ i -eq 4]; then ## Each time a network id field is output and a dot is output, then append
echo ""
else
echo -n "."
fi
done
[[email protected] 9_2] #
7. Exercise: Enter the number of rows and columns in an interactive way and print out a rectangle?
[[email protected] 9_2] #cat rectangle.sh
#! / bin / bash
read -p "input line number:" x
read -p "input colume number:" y
for row in `seq $ x`; do ## Print multiple lines with specified number of lines
for col in `seq $ y`; do ## print a line by specifying the number of columns
echo -e "* \ c"
done
echo ## Line break after printing each line
done
Optimized version: add color display and flash
[[email protected] 9_2] #cat rectangle.sh
#! / bin / bash
read -p "input line number:" x
read -p "input colume number:" y
for row in `seq $ x`; do ## Print multiple lines with specified number of lines
for col in `seq $ y`; do ## print a line by specifying the number of columns
color = $ [RANDOM% 7 + 31] ## RANDOM% 7 means 0-6, +31 is 31-37
echo -e "\ 033 [1; 5; $ {color} m * \ 033 [0m \ c" ## 1 highlights, 5 flashes, \ c goes to the end of the line means no line break
done
echo ## Line break after printing each line
done
[[email protected] 9_2] #
8. Exercise: Printing an isosceles triangle
Use the second syntax of for
[[email protected] 9_4] #cat fortriangle.sh
#! / bin / bash
read -p "Please input a line number:" line
for ((i = 1; i <= line; i ++)); do
for ((j = 1; j <= $ [line-i]; j ++)); do
echo -n ""
done
for ((k = 1; k <= $ [2 * i-1]; k ++)); do
echo -n "*"
done
echo
done
9. Print the nine nine multiplication table
method 1:
[[email protected] 9_4] #vim multi.sh
#! / bin / bash
for i in {1..9}; do ## The outer loop determines how many lines to play, i is equivalent to the line number
for j in `seq $ i`; do ## j means how many times does one line loop?
echo -e "$ j * $ i = $ (($ j * $ i)) \ t \ c" ## Calculate the results of $ j * $ i, separated by tabs, without line breaks;
done
echo ## The position of echo means to wrap after printing a line;
done
[[email protected] 9_4] #sh multi.sh
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 = 81
Idea: To find the pattern, the first number is the column number and the second number is the line number;
Print one line first, and then print multiple lines in a loop. When printing a line, how many times do you need to calculate the loop? —————— Finally found that the line number determines the number of cycles
Method 2: C language style
[[email protected] 9_4] #cat for_mult.sh
#! / bin / bash
for ((i = 1; i <= 9; i ++)); do
for ((j = 1; j <= i; j ++)); do
echo -e "$ j * $ i = $ [j * i] \ t \ c"
done
echo
done
10. Create 10 html files in the / testdir directory, the file name format is number N (from 1 to 10) plus 8 random letters, such as: 1AbCdeFgH.html
[[email protected] 9_4] #vim create.sh
#! / bin / bash
for i in {1..10}; do
touch $ i`tr -dc "0-9a-zA-Z" </ dev / urandom | head -c8`
done
Fourth, the while loop of the loop
[[email protected] 9_4] #vim while.sh
#! / bin / bash
sum = 0
i = 1
while [$ i -le 100]; do
let sum + = i
let i ++
done
echo sum = $ sum "while.sh" [New] 8L, 86C written
[[email protected] 9_4] #sh while.sh
sum = 5050
2. Exercise: Nine Nine Multiplication Table
9_4] #vim whilemult.sh
#! / bin / bash
i = 1
while [$ i -le 9]; do
j = 1
while [$ j -le $ i]; do
echo -e "$ j * $ i = $ [$ j * $ i] \ t \ c"
let j ++
done
echo
let i ++
done
[[email protected] 9_4] #sh whilemult.sh
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 =
3. Exercise: Printing an isosceles triangle
[email protected] 9_4] #cat while_triangle.sh
#! / bin / bash
read -p "Please input a line number:" line
i = 1 ## Print multiple lines
while ["$ i" -le "$ line"]; do
## print space ## Print space
j = 1
while ["$ j" -le $ [line-i]]; do
echo -n "" ## Or use echo -e "\ c"
let j ++
done
## print * ## Print * the number of
k = 1
while ["$ k" -le $ [2 * i-1]]; do
echo -n "*"
let k ++
done
let i ++
echo
done
[[email protected] 9_4] #sh while_triangle.sh
Please input a line number: 10
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
Idea: first print out the space —————— then print the number of *
Define the total number of lines: line
Current line: i
Current column: j
Middle column = total number of lines
The number of the current line from the beginning to the middle = i
space = line-i
Number of current lines = 2i-1
4. Exercise: Monitor the status of httpd service?
#! / bin / bash
SLEEPTIME = 10
while:; do ##: Both true and true
if killall -0 httpd &> / dev / null; then ## kill -0 indicates whether the monitoring process is running
true
else
service httpd restart
echo "At` date + ‘% F% T’` httpd restart" >> /var/log/checkhttpd.log
fi
sleep $ SLEEPTIME ## wait time
done
## It is recommended to use nohup script & put it in the background for execution, the terminal exit will not affect the execution.
5. Exercise: Write a script, use the variable RANDOM to generate 10 random numbers, output the 10 numbers, and display the maximum and minimum values
[[email protected] 9_4] #cat formaxmin.sh
#! / bin / bash
echo -e "random list: \ c"
for ((i = 0; i <10; i ++)); do
rand = $ RANDOM
echo -e "$ rand \ c"
if [$ i -eq 0]; then ## The first random number has no comparable number, so it is both the maximum and minimum;
max = $ rand
min = $ rand
fi
if [$ max -lt $ rand]; then ## If the random number is greater than the maximum value, replace rand with the maximum value;
max = $ rand
elif [$ min -gt $ rand]; then ## Otherwise, it is false, that is, the random number is <max, and <min, then it is replaced with the minimum value.
min = $ rand
else
true ## If it is other conditions, the default
fi
done
echo
echo max is $ max
echo min is $ min
effect:
[[email protected] 9_4] #sh formaxmin.sh
random list: 18428 5303 6933 16210 2577 4107 23750 16836 3435 14399
max is 23750
min is 2577
Five, the loop of the loop
Note: true, exit
Is false, execute the loop statement
1. Exercise: Check the system login user, if there is a hacker login user, kick out?
[[email protected] 9_4] #cat untiltest.sh
#! / bin / bash
until who | grep -q "^ hacker \>"; do
sleep 3
done
## If a hacker user is logging in, log out of the script and execute the following pkill statement.
pkill -9 -U hacker ## Note that pkill -9 can kill all processes of the user.
## Optimized version: Do not exit the script, enter an endless loop, once the hacker logs in, he will directly kick out
[[email protected] 9_4] #cat untiltest.sh
#! / bin / bash
until false; do ## If false, enter an endless loop
who | grep -q "^ hacker \>" && pkill -9 -U hacker
sleep 3
done
Other small exercises 1. Exercise: Randomly generate numbers within 10 to realize word guessing games. Prompt to be larger or smaller, exit if equal
#! / bin / bash
rand = $ [RANDOM% 11] ## Generate random numbers 0-10
while read -p "input a number:" num; do
if [[! $ num = ~ ^ [0-9] + $]]; then ## Due to direct comparison, not
If it is a number, an error will be reported, so make a judgment;
echo "Please input a digit"
continue ## End this loop
elif [$ num -gt $ rand]; then
echo $ num is greater
elif [$ num -lt $ rand]; then
echo $ num is little
else
echo "guess OK"
break ## Exit the entire loop
fi
done
2. Exercise: Read the df information line by line, and then judge whether the utilization rate of the partition is greater than 8, and prompt if it is greater
method 1:
[[email protected] 9_4] #cat diskcheck.sh
#! / bin / bash
df | sed -n "/ sd / p" | while read line; do
name = `echo $ line | tr -s" "% | cut -d% -f1` ## Process each line read by echo $ line
used = `echo $ line | tr -s" "% | cut -d% -f5`
if [$ used -gt 8]; then
echo "$ name will be full; $ used%"
fi
done
[[email protected] 9_4] #sh diskcheck.sh
/ dev / sda2 will be full; 9%
/ dev / sda1 will be full; 16%
Method 2:
#! / bin / bash
df | while read line; do
if [["$ line" = ~ /dev/sd.*]]; then
used = `echo $ line | tr -s" "% | cut -d% -f5`
if [$ used -gt 8]; then
echo "$ line" | tr -s "": | cut -d: -f1,5
fi
fi
done
[[email protected] 9_4] #sh diskcheck1.sh
/ dev / sda2: 9%
/ dev / sda1: 16%
3. Exercise: Scan each line of the / etc / passwd file. If the GECOS field is found to be empty, fill in the user name and unit phone number 62985600, and prompt that the user's GECOS information was modified successfully
[[email protected] 9_4] #cat user.sh
#! / bin / bash
while read line; do
GECOS = `echo $ line | cut -d: -f5`
USER = `echo $ line | cut -d: -f1`
[-z "$ GECOS"] && chfn -f $ USER -p 2985600 $ USER &> / dev / null;
done </ etc / passwd
4. Exercise: ss -nt to view the IP of the access connection. If it reaches two, set the firewall policy to refuse the connection.
[[email protected] 9_4] #vim test.sh
#! / bin / bash
ss -nt | sed -nr '/ESTAB/s/.* (. *):. * / \ 1 / p' | sort | uniq -c | while read line; do ## Take out the ip and count the times, then Line reading
IP = `echo $ line | cut -d" "-f2`
num = `echo $ line | cut -d" "-f1`
if ["$ num" -ge 2]; then
iptables -A INPUT -s $ IP -j REJECT ## If the number of connections is> 2, use firewall policy to block the connection
else
true
fi
done
5.select menu
Syntax: select: select NAME [in WORDS ...;] do COMMANDS; done
[[email protected] ~] #cat select.sh
#! / bin / bash
PS3 = "please choose a digit:" ## PS3 is specifically used to provide input
select MENU in jiaozi lamian mifan daoxiaomian quit; do ## in the parameters behind the default one by one according to the serial number 1 2 3 4
case $ MENU in
jiaozi)
echo "Your choose is $ REPLY" ## Variable REPLY is specially used to store the result of user input
echo "$ MENU price is 20"
;;
lamian)
echo "Your choose is $ REPLY"
echo "$ MENU price is 15"
;;
mifan)
echo "Your choose is $ REPLY"
echo "$ MENU price is 18"
;;
daoxiaomian)
echo "Your choose is $ REPLY"
echo "$ MENU price is 12"
;;
quit)
echo "Your choose is $ REPLY"
break
;;
*)
echo "Your choose is $ REPLY"
echo "choose again"
;;
esac
done
effect:
[[email protected] ~] #sh select.sh
1) jiaozi
2) lamian
3) mifan
4) daoxiaomian
5) quit
please choose a digit: 1
Your choose is 1
jiaozi price is 20
please choose a digit: 2
Your choose is 2
lamian price is 15
please choose a digit: 5
Your choose is 5
shell script exercise