文章目录
1.for语句
1.1 作用
为循环执行动作
1.2 for语句结构:
for 定义变量
do 使用变量,执行动作
done 结束标志
1.3 for语句基本格式
1.3.1 格式1
[root@server1 mnt]# vim for.sh
#!/bin/bash
for I in {1..10}
do
echo $I
done
[root@server1 mnt]# sh for.sh
1
2
3
4
5
6
7
8
9
10
[root@server1 mnt]# vim for.sh
#!/bin/bash
for I in {10..1} 还可以倒着写,从10到1
do
echo $I
done
[root@server1 mnt]# sh for.sh
10
9
8
7
6
5
4
3
2
1
1.3.2 格式2
[root@server1 mnt]# vim for.sh
#!/bin/bash
for I in `seq 1 10`
do
echo $I
done
[root@server1 mnt]# sh for.sh
1
2
3
4
5
6
7
8
9
10
[root@server1 mnt]# vim for.sh
#!/bin/bash
for I in `seq 1 2 10` 可以设置步长,2为步长
do
echo $I
done
[root@server1 mnt]# sh for.sh
1
3
5
7
9
1.3.3 格式3
[root@server1 mnt]# vim for.sh
#!/bin/bash
for ((I=1;I<=10;I++)) I++ 表示I每次自加1
do
echo $I
done
[root@server1 mnt]# sh for.sh
1
2
3
4
5
6
7
8
9
10
[root@server1 mnt]# vim for.sh
#!/bin/bash
for ((I=10;I>0;I--)) 倒着写
do
echo $I
done
[root@server1 mnt]# sh for.sh
10
9
8
7
6
5
4
3
2
1
0
2.判断循环语句
while …do语句
作用:
条件为真执行动作
语句结构
while ture 条件为真
do 条件成立所循环的动作
down
[root@server1 mnt]# vim while.sh
#!/bin/bash
for I in {1..10}
do
while [ "$I" = "4" ]
do
read -p "Please input number: " I
echo $I
done
echo $I
done
[root@server1 mnt]# sh while.sh
1
2
3
Please input number: 4
4
Please input number: 4
4
[root@server1 mnt]# vim while.sh
#!/bin/bash
for I in {1..10}
do
while [ "$I" = "4" ]
do
echo $I 一直循环4
done
echo $I
done
[root@server1 mnt]# sh while.sh
4
4
4
4
4
4
4
4
[root@server1 mnt]# vim while.sh
#!/bin/bash
while true 条件成立
do
read -p "Please input word: " WORD
while [ "$WORD" = "exit" ]
do
exit
done
echo $WORD
done
[root@server1 mnt]# sh while.sh
Please input word: lee
lee
Please input word: westos
westos
Please input word: exit
[root@server1 mnt]# vim while.sh
6 #!/bin/bash
7 until false 表示当条件不成立的时候
8 do
9 read -p "Please input word: " WORD
10 while [ "$WORD" = "exit" ]
11 do
12 exit
13 done
14
15 echo $WORD
16 done
[root@server1 mnt]# sh while.sh 执行
Please input word: lee
lee
Please input word: poo
poo
Please input word: exit
3.多条件判断语句
if…then…elif…then…else…fi 语句
if 首次判定
then 条件成立执行的动作
elif 当首次判定不成立时再次判定
then 条件成立执行的动作
… elif可以书写多次
else 所有条件不成立执行的动作
fi 结束
[root@server1 mnt]# vim if.sh
#!/bin/bash
if [ -z "$1"]
then
echo "Please input a number following $0 !!"
elif [ "$1" -lt "0" ]
then
echo no
elif [ "$1" -gt "10" ]
then
echo no
else
echo yes
fi
[root@server1 mnt]# sh if.sh 执行
Please input a number following if.sh !!
[root@server1 mnt]# sh if.sh 11
no
[root@server1 mnt]# sh if.sh 10
yes
如何判断过滤成数字
[root@server1 mnt]# grep [[:alpha:][:punct:]] /etc/passwd && echo no || echo yes
4.shell中的选择语句
格式
case $1 in
word1|WORD1)
action1 ##动作1
;;
word2|WORD2)
action2 ##动作2
;;
*)
action3 ##动作3
esac
#!/bin/bash
case $1 in
westos|WESTOS)
echo linux
;;
linux|LINUX)
echo westos
;;
*)
echo error
esac
[root@server1 mnt]# sh case.sh westos 执行
linux
[root@server1 mnt]# sh case.sh linux
westos
[root@server1 mnt]# sh case.sh
error
5. shell中的自动应当方案
问题:
[root@server1 mnt]# vim ask.sh
#!/bin/bash
read -p "what's your name:" NAME
read -p "How old are you: " AGE
read -p "Which subject: " OBJ
read -p "Are you happy? " FEEL
echo $NAME is $AGE\'s old study $OBJ feel $FEEL
[root@server1 mnt]# sh ask.sh 执行,交互式
what's your name:lee
How old are you: 30
Which subject: shell
Are you ok? happy
lee is 30's old study shell feel happy
[root@server1 mnt]# vim test.sh 多行录入,实现自动应答
#!/bin/bash
/mnt/ask.sh << EOF
lee
20
linux
happy
EOF
[root@server1 mnt]# sh test.sh 执行
lee is 20's old study linux feel happy
[root@server1 mnt]# vim ask.sh 如果将其中一个问题注释
#!/bin/bash
read -p "what's your name:" NAME
#read -p "How old are you: " AGE 注释掉
read -p "Which subject: " OBJ
read -p "Are you happy? " FEEL
echo $NAME is $AGE\'s old study $OBJ feel $happy
[root@server1 mnt]# sh test.sh 执行多行录入自动应答,发现结果混乱
lee is 20's old study linux feel happy 用多行录入实现自动应答,只能解决顺序不变问题都会出现的
上述问题可用expect解决
[root@server1 mnt]# yum install expect -y 安装
[root@server1 mnt]# vim answer.exp
1 #!/usr/bin/expect
2 spawn /mnt/ask.sh
3 expect { 遇到的问题及应答
4 "name" { send "lee\r";exp_continue }
5 "old" { send "20\r";exp_continue }
6 "subject" {send "shell\r";exp_continue }
7 "happy" { send "happy\r" }
8 }
9
10 expect eof 表示回答问题以后,立即退出expect环境,如果是interact表示不退出expect环境
[root@server1 mnt]# expect answer.exp 执行
spawn /mnt/ask.sh
what's your name:lee
How old are you: 20
Which subject: shell
Are you happy? happy
lee is 20's old study shell feel happy
[root@server1 mnt]# vim ask.sh
#!/bin/bash
read -p "what's your name:" NAME
#read -p "How old are you: " AGE 注释掉
read -p "Which subject: " OBJ
read -p "Are you happy? " FEEL
echo $NAME is $AGE\'s old study $OBJ feel $FEEL
[root@server1 mnt]# expect answer.exp 执行
spawn /mnt/ask.sh
what's your name:lee
Which subject: shell
Are you happy? happy
lee is 's old study shell feel happy 即使注释掉一行回答也是正确的
优化脚本
[root@server1 mnt]# vim answer.exp
1 #!/usr/bin/expect
2 set timeout 2 表示停顿超过2s忽略
3 set NAME [ lindex $argv 0 ] 设置变量,$argv 0 表示answer.exp脚本后面跟的第一串字符
4 set AGE [ lindex $argv 1 ] $argv 1表示answer.exp脚本后面跟的第二串字符
5 set OBJ [ lindex $argv 2 ] $argv 2表示answer.exp脚本后面跟的第三串字符
6 set FEEL [ lindex $argv 3 ] $argv 3 表示answer.exp脚本后面跟的第四串字符
7 spawn /mnt/ask.sh
8 expect {
9 "name" { send "$NAME\r";exp_continue } \r表示回车
10 "old" { send "$AGE\r";exp_continue }
11 "subject" {send "$OBJ\r";exp_continue }
12 "happy" { send "$FEEL\r" }
13 }
14
15 expect eof
[root@server1 mnt]# expect answer.exp 后面没跟,答案都是空的
spawn /mnt/ask.sh
what's your name:
Which subject:
Are you happy?
is 's old study feel
[root@server1 mnt]# expect answer.exp lee 20
spawn /mnt/ask.sh
what's your name:lee
How old are you: 20
Which subject:
Are you happy?
lee is 20's old study feel
如何将shell和expect结合起来
[root@server1 mnt]# vim test.sh
#!/bin/bash
/usr/bin/expect << EOF
spawn /mnt/ask.sh
expect {
"name" { send "$1\r";exp_continue} EOF中间内容都在expect环境执行
"old" { send "$2\r";exp_continue}
"subject" { send "$3\r";exp_continue}
"happy" { send "$4\r"}
}
expect eof
EOF
echo hello westos
date
[root@server1 mnt]# sh test.sh lee 30 linux happy 执行
spawn /mnt/ask.sh
what's your name:lee
How old are you: 30
Which subject: linux
Are you happy? happy
lee is 30's old study linux feel happy
hello westos
Tue Oct 11 05:06:58 CST 2022
6、shell中的控制器
break 终止当此次循环提前进入下个循环
continue 终止当前所在语句所有动作进行语句外的其他动作
exit 脚本退出
return 表示退出函数,函数以外的继续执行
6.1 exit
[root@server1 mnt]# ls
test.sh
[root@server1 mnt]# echo $? $?表示退出直
0
[root@server1 mnt]# vim test.sh
#!/bin/bash
ls /mnt &> /dev/null
[root@server1 mnt]# sh test.sh
[root@server1 mnt]# echo $? 退出直为0
0
[root@server1 mnt]# vim test.sh
#!/bin/bash
ls /mnt &> /dev/null
exit 1 设置退出直为1
[root@server1 mnt]# sh test.sh
[root@server1 mnt]# echo $? 退出直为1
1
[root@server1 mnt]# vim test.sh
#!/bin/bash
for I in {1..10}
do
if [ "$I" = "4" ]
then
echo luck number
exit
fi
echo $I
done
echo end
[root@server1 mnt]# sh test.sh 遇到exit直接退出
1
2
3
luck number
6.2 continue
[root@server1 mnt]# vim test.sh
#!/bin/bash
for I in {1..10}
do
if [ "$I" = "4" ] 表示终止"$I" = "4"的循环,到continue为止,后面的动作echo $I 就放弃了,循环"$I" = "4"外的循化依然执行
then
echo luck number
continue
fi
echo $I
done
echo end
[root@server1 mnt]# sh test.sh
1
2
3
luck number
5
6
7
8
9
10
end
6.3 break
[root@server1 mnt]# vim test.sh
#!/bin/bash
for I in {1..10}
do
if [ "$I" = "4" ]
then
echo luck number
break 表示终止所在for循环,for循环以外的仍然执行
fi
echo $I
done
echo end
[root@server1 mnt]# sh test.sh 执行
1
2
3
luck number
end
6.4 return
6 #!/bin/bash
7 TEST()
8 {
9 for I in {1..10}
10 do
11 if [ "$I" = "4" ]
12 then
13 echo luck number
14 return 表示退出函数,函数以外的继续执行
15 fi
16
17 echo $I
18
19 done
20
21 echo end
22 }
23 TEST
24 echo ==========================
[root@server1 mnt]# sh test.sh 执行
1
2
3
luck number
==========================
7.练习
7.1字符长度判定
在westos.txt中输出字符长度小于8的每一列
/etc/passwd文件的第六列没有home关键字并且以bash结尾的行
[root@server1 mnt]# awk -F : '$6!~/home/&&/bash$/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
7.2批量添加用户
执行 usercreate.sh userlist ,userlist里面的用户全部建立出来,用户存在报错,用户不存在建立用户并且密码设置为westos
[root@server1 mnt]# vim userlist
1 user1
2 user2
3 user3
[root@server1 mnt]# vim usercreate.sh 执行
1 ##################
2 # AUthor
3 # Create_Time: 2022/10/11
4 ##################
5
6 #!/bin/bash
7 [ -z "$1" ] && {
8 echo "Please input userlist file follow $0 !!"
9 exit
10 }
11
12 [ ! -e "$1" ] && {
13 echo "$1 is not exist"
14 exit
15 }
16
17 for USERNAME in `cat $1`
18 do
19 id $USERNAME &> /dev/null && {
20 echo $USERNAME is exist !!
21 }||{
22 useradd $USERNAME
23 echo westos | passwd --stdin $USERNAME
24 }
25 done
[root@server1 mnt]# sh usercreate.sh userlis
userlis is not exist
[root@server1 mnt]# sh usercreate.sh userlist
Changing password for user user1.
passwd: all authentication tokens updated successfully.
Changing password for user user2.
passwd: all authentication tokens updated successfully.
Changing password for user user3.
passwd: all authentication tokens updated successfully.
[root@server1 mnt]# sh usercreate.sh userlist
user1 is exist !!
user2 is exist !!
user3 is exist !!
7.3文件类型判定
[root@server1 mnt]# vim create_filetype.sh
1 ##################
2 # AUthor
3 # Create_Time: 2022/10/12
4 ##################
5
6 #!/bin/bash
7 if [ -z "$*" ]
8 then
9 echo Please input filename following $0 !!
10 elif [ ! -e "$*" ]
11 then
12 echo file is not exist !!
13 elif [ -L "$*" ]
14 then
15 echo $* is link
16 elif [ -f "$*" ]
17 then
18 echo $* is common file
19 elif [ -d "$*" ]
20 then
21 echo $* is directory
22 fi
[root@server1 mnt]# sh create_filetype.sh
Please input filename following create_filetype.sh !!
[root@server1 mnt]# sh create_filetype.sh /mnt/
/mnt/ is directory
[root@server1 mnt]# sh create_filetype.sh /mnt/test.sh
/mnt/test.sh is common file
7.4 查找字符长度
取出文件westos.txt内容单词字母个数小于8的
cat westos.txt
Operating System: Red Hat Enterprise Linux 8.2 (Ootpa)
[root@server1 mnt]# vim westos.sh
1 ##################
2 # AUthor
3 # Create_Time: 2022/10/12
4 ##################
5
6 #!/bin/bash
7 if [ -n "$1" ]
8 then
9 for WORD in `cat $1`
10 do
11 LENGTH=`echo -n $WORD|wc -m` -n表示去掉换行符
12 if [ $LENGTH -lt "8" ]
13 then
14 echo $WORD
15 fi
16 done
17 else
18 echo Please input file following $0 !!
19 fi
[root@server1 mnt]# sh westos.sh westos.txt 执行
System:
Red
Hat
Linux
8.2
(Ootpa)
7.4 网络检测脚本
检测网络172.25.254.1…10网络是否通畅
[root@server1 mnt]# vim check_net.sh
1 ##################
2 # AUthor
3 # Create_Time: 2022/10/12
4 ##################
5
6 #!/bin/bash
7 for HOST in {1..10} 50
8 do
9 ping -c1 -w1 172.25.254.$HOST &> /dev/null && {
10 echo 172.25.254.$HOST is up
11 }||{
12 echo 172.25.254.$HOST is down
13 }
14 done
[root@server1 mnt]# sh check_net.sh 执行
172.25.254.1 is down
172.25.254.2 is down
172.25.254.3 is down
172.25.254.4 is down
172.25.254.5 is down
172.25.254.6 is down
172.25.254.7 is down
172.25.254.8 is down
172.25.254.9 is down
172.25.254.10 is down
172.25.254.50 is up
7.5 自动应答脚本
[root@server1 mnt]# vim check_host.sh
##################
# AUthor
# Create_Time: 2022/10/12
##################
#!/bin/bash
AUTH_SSH()
{
/usr/bin/expect <<EOF
spawn ssh -l root $1 hostname $1代表AUTH_SSH函数后的第一串字符
expect {
"yes/no" { send "yes\r";exp_continue }
"password" { send "westos\r"}
}
expect eof
EOF
}
[ -z "$*" ] && {
echo "Please input ip address following $0 !!"
exit
}
ping -c1 -w1 $* &> /dev/null && {
AUTH_SSH $* | tail -n 1 AUTH_SSH $*表示 $1
}||{
echo "$* is down"
}
[root@server1 mnt]# sh check_host.sh 172.25.254.50 执行
foundation50
[root@server1 mnt]# sh check_host.sh 172.25.254.51
172.25.254.51 is down
7.6 软件管理脚本
##################
# AUthor
# Create_Time: 2022/10/12
##################
#!/bin/bash
case $1 in
install)
read -p "Please input software: " SOFTWARE
dnf list $SOFTWARE &> /dev/null && {
rpm -q $SOFTWARE &> /dev/null && {
echo $SOFTWARE is installed
}||{
echo dnf install $SOFTWARE -y &> /dev/null && echo $SOFTWARE install successful !!
}
}||{
echo $SOFTWARE is not exist !!
}
;;
delete)
read -p "Please input software: " SOFTWARE
dnf list $SOFTWARE &> /dev/null && {
rpm -q $SOFTWARE &> /dev/null && {
dnf remove $SOFTWARE -y &> /dev/null && echo $SOFTWARE is delete successful !!
}||{
echo $SOFTWARE is not installed
}
}||{
echo $SOFTWARE is not exist
}
;;
*)
echo "Please input install or delete following $0 !!"
esac