1.for 语句
for NUM in 1 2 3
for NUM in {1…3}
for NUM in `seq 1 3` 或者 for NUM in `seq 1 2 10`
do
done
注:seq 设定步长,每隔几个做一次
(1)正序输出1-10
#!/bin/bash
for i in {1..10}
do
echo $i
done
#!/bin/bash
for i in `seq 1 10`
do
echo $i
done
#!/bin/bash
for i in 1 2 3
do
echo $i
done
#!/bin/bash
for i in `ls /mnt`
do
echo $i
done
[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh
calculator.sh
numtest.sh
test.sh
time_count1.sh
time_count.sh
[root@shell_example mnt]# ls
calculator.sh numtest.sh test.sh time_count1.sh time_count.sh
#!/bin/bash
for i in `seq 1 2 10`
do
echo $i
done
[root@shell_example mnt]# vim jishu.sh
[root@shell_example mnt]# sh jishu.sh
1
3
5
7
9
#!/bin/bash
for i in `seq 2 2 10`
do
echo $i
done
[root@shell_example mnt]# vim jishu.sh
[root@shell_example mnt]# sh jishu.sh
2
4
6
8
10
#!/bin/bash
[ -z "$1" ]&&{
echo ERROR
exit
}
clear
for ((SEC=$1;SEC>0;SEC--))
do
echo -n "After ${SEC}s is end "
echo -ne "\r"
sleep 1
done
[root@shell_example mnt]# vim countdown.sh
[root@shell_example mnt]# sh countdown.sh
ERROR
[root@shell_example mnt]# sh countdown.sh 30
注意:
"After ${SEC}s is end "后一定要有空格,因为两位数和一位数所占的字符数不同,需要空格来占位
练习2:编写一个脚本,使其在没有输入任何内容的时候报错,连通主机是输出ip is up ,不能连通时输出ip is down
首先编辑一个文件写入需要测试的ip
[root@shell_example mnt]# vim ipfile
[root@shell_example mnt]# cat ipfile
#!/bin/bash
[ -z "$1" ] && {
echo "plesae input filename"
exit
}
for i in `cat $1`
do
ping -c 1 -w 1 $i &>/dev/null && {
echo $i is up
} || {
echo $i is down
}
done
[root@shell_example mnt]# vim ip_check.sh
[root@shell_example mnt]# sh ip_check.sh
plesae input filename
[root@shell_example mnt]# sh ip_check.sh ipfile
172.25.254.1 is down
172.25.254.3 is down
172.25.254.10 is down
172.25.254.68 is up
172.25.254.127 is up
#!/bin/bash
[ -z "$1" ] && {
echo "plesae input filename"
exit
}
Max_line=`sed -n '$=' $1`
for i in $(seq 1 $Max_Line)
do
ip=`sed -n "${i}p" $1`
ping -c 1 -w 1 $ip &>/dev/null && {
echo $i is up
} || {
echo $i is down
}
done
while 条件
do
done
while表示条件为真时做什么
until表示条件为假时做什么
(1)编写一个脚本,输入什么输出什么
#!/bin/bash
while true
do
read -p "Please input a word: " WORD
echo $WORD
done
[root@shell_example mnt]# vim whiletest.sh
[root@shell_example mnt]# sh whiletest.sh
Please input a word: hello
hello
Please input a word: test
test
Please input a word: hahah
hahah
Please input a word: ^C
#!/bin/bash
until true
do
read -p "Please input a word: " WORD
while [ "$WORD" = "exit" ]
do
echo bye
exit 0
done
echo $WORD
done
[root@shell_example mnt]# vim whiletest.sh
[root@shell_example mnt]# sh whiletest.sh
#!/bin/bash
until false ##条件不成立时不执行
do
read -p "Please input a word: " WORD
while [ "$WORD" = "exit" ]
do
echo bye
exit 0
done
echo $WORD
done
[root@shell_example mnt]# vim whiletest.sh
[root@shell_example mnt]# sh whiletest.sh
Please input a word: hello
hello
Please input a word: new
new
Please input a word: old
old
Please input a word: exit
bye
if
then
elif
then
…
else
fi
例1:编写一个脚本当输入a时输出apple,输入b时输出banana,输入其他字符时输出error
#!/bin/bash
if
[ "$1" = "a" ]
then
echo apple
elif
[ "$1" = "b" ]
then
echo banana
else
echo error
fi
[root@shell_example mnt]# vim iftest.sh
[root@shell_example mnt]# sh iftest.sh b
banana
[root@shell_example mnt]# sh iftest.sh a
apple
[root@shell_example mnt]# sh iftest.sh
error
#!/bin/bash
while true
do
read -p "please input a filename: " FILE
[ -e "$FILE" ] || {
echo "this file is not exist"
}
if
[ -L "$FILE" ]
then
echo "$FILE is a link "
elif
[ -f "$FILE" ]
then
echo "$FILE is a file "
elif
[ -d "$FILE" ]
then
echo "$FILE is a directory "
elif
[ -b "$FILE" ]
then
echo "$FILE is a block "
elif
[ -c "$FILE" ]
then
echo "$FILE is a character "
elif
[ -s "$FILE" ]
then
echo "$FILE is a socket "
elif
[ "$FILE" = "exit" ]
then
exit
fi
done
[root@shell_example mnt]# vim filetype.sh
[root@shell_example mnt]# sh filetype.sh
please input a filename: /mnt
/mnt is a directory
please input a filename: /etc/passwd
/etc/passwd is a file
please input a filename: exit
练习2:用if语句编写一个脚本,设计一个1分10秒的倒计时的定时器
#!/bin/bash
SEC=10
MIN=1
for ((;SEC>=0;SEC--))
do
if
[ "$SEC" -eq "0" -a "$MIN" -eq "0" ]
then
exit 0
elif
[ "$SEC" -eq "0" -a "$MIN" -ge "0" ]
then
echo -n "After "$MIN"m:"$SEC"s is end "
echo -ne "\r"
SEC=59
((MIN--))
sleep 1
clear
fi
echo "After "$MIN"m:"$SEC"s is end "
echo -ne "\r"
sleep 1
clear
done
case
word1 )
action1
;;
word2)
action2
\;;
*)
action_last
esac
例:
编写一个脚本,输入a返回apache,输入b返回backup,输入c返回chrony,输入其他字符时返回error
#!/bin/bash
case $1 in
a)
echo apache
;;
b)
echo backup
;;
c)
echo chrony
;;
*)
echo error
esac
[root@shell_example mnt]# vim casetest.sh
[root@shell_example mnt]# sh casetest.sh
error
[root@shell_example mnt]# sh casetest.sh a
apache
[root@shell_example mnt]# sh casetest.sh b
backup
[root@shell_example mnt]# sh casetest.sh c
chrony
比较case语句和if语句:
case和if功能相同但效率不一样,if需要判断多次,一个一个查找对应的条件,而case会直接查找想要的条件
在字符匹配的时候用case
在判断的时候用if
(1)这里可以利用之前编写的iftest.sh脚本,和刚刚编写的casetest.sh脚本作比较,两者的功能是一样的,都是输入一个字符返回一个对应的字符串
(2)我们可以sh -x执行脚本观察循环的顺序,可以看到执行if循环额脚本时是有先后顺序的,这个顺序就是见本中编写的前后顺序,当输入b时循环了两次才找到对应的字符串
[root@shell_example mnt]# sh -x iftest.sh a
+ '[' a = a ']'
+ echo apple
apple
[root@shell_example mnt]# sh -x iftest.sh b
+ '[' b = a ']'
+ '[' b = b ']'
+ echo banana
banana
(3)但是在执行case语句时没有先后顺序,不管输入哪个字符都只循环一次
[root@shell_example mnt]# sh -x casetest.sh a
+ case $1 in
+ echo apache
apache
[root@shell_example mnt]# sh -x casetest.sh b
+ case $1 in
+ echo backup
backup
expect | 是自动应答命令用于交互式命令的自动执行 |
---|---|
spawn | 是 expect 中的监控程序,其运行后会监控命令提出的交互问题 |
send | 发送问题答案给交互命令 |
“\r” | 表示回车 |
exp_continue | 表示当问题不存在时继续回答下面的问题 |
expect eof | 表示问题回答完毕退出 expect 环境 |
interact | 表示问题回答完毕留在交互界面 |
set NAME [ lindex $argv n ] | 定义变量 |
实验:
1.创建两个脚本,一个作为问题,一个作为答案,改变其中一个脚本的信息另一个不变时和会出现问题与但阿不匹配的状况
(1)创建一个脚本作为提问的,给他加上可执行权限,运行结果如下
#!/bin/bash
read -p "What's your name: " NAME
read -p "How old are you: " AGE
read -p "Which objective study: " OBJ
read -p "Are you happy? " FEEL
echo $NAME is $AGE\'s old study $OBJ feel $FEEL
[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# chmod +x ask.sh
[root@shell_example mnt]# sh ask.sh
What's your name: yyy
How old are you: 18
Which objective study: linux
Are you happy? happy
yyy is 18's old study linux feel happy
(2)再创建一个脚本将上一个脚本中问题的答案重定向到ask.sh中去
#!/bin/bash
/mnt/ask.sh <
[root@shell_example mnt]# vim answer.sh
[root@shell_example mnt]# sh answer.sh
haha is 10's old study java feel sad
(3)此时将ask.sh中的某一个问题注释掉,另一个脚本中的内容不做任何改变,运行answer.sh脚本后会出现问题与答案不匹配的情况
#!/bin/bash
read -p "What's your name: " NAME
#read -p "How old are you: " AGE
read -p "Which objective study: " OBJ
read -p "Are you happy? " FEEL
echo $NAME is $AGE\'s old study $OBJ feel $FEEL
[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# sh answer.sh
haha is 's old study 10 feel java
2.利用expect创建两个脚本一个时问题一个是答案,尽管改变了其中一个的信息两个脚本相匹配时也不会出错
(1)下载安装包
[root@shell_example mnt]# yum install expect.x86_64 -y
(2)下载完成后直接可以使用expect命令,这里退出要用exit
[root@shell_example mnt]# expect
expect1.1> exit
[root@shell_example mnt]# which expect
/usr/bin/expect
(4)编辑test.exp文件并写入答案(将ask.sh中的注释还原),这里的脚本文件必须以.exp结尾
#!/usr/bin/expect
spawn /mnt/ask.sh
expect "name"
send "yue\r"
expect "old"
send "18\r"
expect "objective"
send "uklele\r"
expect "happy"
send "very happy\r"
interact
[root@shell_example mnt]# vim test.exp
[root@shell_example mnt]# expect test.exp
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Which objective study: uklele
Are you happy? very happy
yue is 18's old study uklele feel very happy
#!/usr/bin/expect
set NAME [ lindex $argv 0 ]
set AGE [ lindex $argv 1 ]
set OBJ [ lindex $argv 2 ]
set FEEL [ lindex $argv 3 ]
spawn /mnt/ask.sh
expect "name"
send "$NAME\r"
expect "old"
send "$AGE\r"
expect "objective"
send "$OBJ\r"
expect "happy"
send "$FEEL\r"
expect eof
测试:
执行脚本时缺少几个变量就会有行的答案为空
(1)变量为空时没有答案输出
[root@shell_example mnt]# vim test.exp
[root@shell_example mnt]# expect test.exp
spawn /mnt/ask.sh
What's your name:
How old are you:
Which objective study:
Are you happy?
is 's old study feel
[root@shell_example mnt]# expect test.exp yue 18 uklele happy
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Which objective study: uklele
Are you happy? happy
yue is 18's old study uklele feel happy
(3)将ask.sh中的某一行注释掉,再次执行test.exp这是在被注释掉的问题那行会停顿一段时间,找不到答案之后他会输出匹配出的错误结果
[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# expect test.exp yue 18 uklele happy
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Are you happy? uklele
happy
yue is 18's old study feel uklele
脚本expect自动打开自己的解释环境,和shell不通用
set timeout 5 提高脚本的执行效率,问题回答不上来就直接放弃
(1)将ask.sh中的内容还原,编辑test.exp并且执行脚本
#!/usr/bin/expect
set NAME [ lindex $argv 0 ]
set AGE [ lindex $argv 1 ]
set OBJ [ lindex $argv 2 ]
set FEEL [ lindex $argv 3 ]
set timeout 5
spawn /mnt/ask.sh
expect {
"name" {send "$NAME\r" ; exp_continue }
"old" {send "$AGE\r" ; exp_continue }
"objective" {send "$OBJ\r" ; exp_continue }
"happy" {send "$FEEL\r" }
}
expect eof
[root@shell_example mnt]# vim test.exp
[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# expect test.exp yue 18 uklele happy
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Which objective study: uklele
Are you happy? happy
yue is 18's old study uklele feel happy
(2)将ask.sh中的一行注释掉,再次运行脚本时被注释掉的问题不会再次出现,所有的问题与答案也会匹配
测试:
[root@shell_example mnt]# vim ask.sh
[root@shell_example mnt]# vim test.exp
[root@shell_example mnt]# expect test.exp yue 18 uklele happy/
spawn /mnt/ask.sh
What's your name: yue
How old are you: 18
Are you happy? happy
yue is 18's old study feel happy
(1)exit n 脚本退出(所在环境),退出值为 n
(2)break 退出当前循环(当前所有循环)
(3)continue 提前结束循环内部的命令,但不终止循环(打破当前循环,进入到下一次循环)
实验:
(1)当叫脚本中没有使用任何控制语句时结果如下
#!/bin/bash
for i in {1..10}
do
if
[ "$i" = "5" ]
then
echo $i
fi
echo $i
done
[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh
#!/bin/bash
for i in {1..10}
do
if
[ "$i" = "5" ]
then
exit 0
fi
echo $i
done
echo westos!!!!!!
[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh
1
2
3
4
#!/bin/bash
for i in {1..10}
do
if
[ "$i" = "5" ]
then
break
fi
echo $i
done
echo westos!!!!!!
[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh
1
2
3
4
westos!!!!!!
#!/bin/bash
for i in {1..10}
do
if
[ "$i" = "5" ]
then
continue
fi
echo $i
done
echo westos!!!!!!
[root@shell_example mnt]# vim test.sh
[root@shell_example mnt]# sh test.sh