if 语句
if
语句通过关系运算符判断表达式的真假来决定执行哪个分支。Shell 有三种 if ... else
语句:
if ... fi 语句;
if ... else ... fi 语句;
if ... elif ... else ... fi 语句;
if ... else 语句
语法
if [ expression ]
then
Statement(s) to be executed if expression is true
fi
如果 expression
返回 true
,then
后边的语句将会被执行;如果返回 false
,不会执行任何语句。最后必须以 fi
来结尾闭合 if
,fi
就是 if
倒过来拼写,后面也会遇见。
expression
和方括号([ ]
)之间必须有空格,否则会有语法错误。
示例
#!/bin/bash
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
fi
if [ $a != $b ]
then
echo "a is not equal to b"
fi
运行结果:
a is not equal to b
if ... else ... fi 语句
语法
if [ expression ]
then
Statement(s) to be executed if expression is true
else
Statement(s) to be executed if expression is not true
fi
如果 expression
返回 true
,那么 then
后边的语句将会被执行;否则,执行 else
后边的语句。
示例
#!/bin/bash
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
else
echo "a is not equal to b"
fi
运行结果:
a is not equal to b
if ... elif ... fi 语句
语法
if [ expression 1 ]
then
Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
Statement(s) to be executed if expression 3 is true
else
Statement(s) to be executed if no expression is true
fi
哪一个 expression
的值为 true
,就执行哪个 expression
后面的语句;如果都为 false
,那么不执行任何语句。
要注意的是,执行完第一个 expression
的值为 true
的后面的语句后,后面的其它分支中即使 expression
的值为 true
它后面的语句也不执行了。
示例
#!/bin/sh
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
elif [ $a -gt $b ]
then
echo "a is greater than b"
elif [ $a -lt $b ]
then
echo "a is less than b"
else
echo "None of the condition met"
fi
运行结果:
a is less than b
expression
的写法可参考【Linux基础(26)之bash中的条件测试】。
for循环
for 循环的执行机制是依次将列表中的元素赋值给变量,每次赋值后立即执行一次循环体,直至列表中的元素用尽才结束。
Shell 中 for 循环的语法如下:
for [变量] in [取值列表]
do
[各种操作]
done
也可使用分号 ;
分割语句写成一行:
for [变量] in [取值列表]; do [各种操作]; done
取值列表有很多类型,大致如下:
枚举值
取值列表可以是枚举的字符串、数值等。
例:
#!/bin/bash
#
for str in 'hello' 'world' '!'
do
echo $str
done
运行结果:
hello
world
!
glob
取值列表还可以是使用 glob 筛选的文件列表。
例:
#!/bin/bash
#
for file in /etc/*.conf; do
echo $file
done
运行结果:
[root@localhost tmpsh]# ./for_2.sh
/etc/asound.conf
/etc/chrony.conf
/etc/dracut.conf
/etc/e2fsck.conf
...
seq
seq
命令能够生成数值列表,这个列表能够被 for
循环迭代。
先了解一下 seq
命令,它的命令格式为:
seq 起始值 [增量] 结束值
不指定增量时默认增量为 1。
例:生成 1-5
之间的数字:
[root@localhost tmpsh]# seq 1 5
1
2
3
4
5
可通过
-w
选项指定生成的数字等长。
下面使用 for
循环迭代一下生成的列表:
#!/bin/bash
#
for num in $(seq 1 5); do
echo "num:$num"
done
运行结果:
num:1
num:2
num:3
num:4
num:5
{..}
for
循环还支持使用 {<num1>..<num2}>
语法来生成 num1
和 num2
之间的数字列表,相当于使用 seq <num1> <num2>
。
例:
#!/bin/bash
#
for num in {1..5}; do
echo "num:$num"
done
运行结果:
num:1
num:2
num:3
num:4
num:5
标准输出流
for
循环可遍历 $(<command>)
的执行结果,前提是 command
的执行结果是输出到标准输出(终端),for
循环回会将标准输出按空格分隔后的每一个单词当作遍历时的变量。
例:
#!/bin/bash
#
for word in $(ls /); do
echo $word
done
运行结果:
bin
boot
dev
etc
...
文件输入流
for
循环还可通过 $(< <file>)
来接受到文件重定向的输入流来遍历一个文件的每一行以空格分隔的每个单词,例:
例:
#!/bin/bash
#
for line in $(< /etc/passwd); do
echo $line
done
运行结果:
[root@localhost tmpsh]# ./for_6.sh
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
...
$@
我们已经知道 $@
可以引用到传入脚本的参数列表,它也可以使用 for
循环来遍历。
例:
# for_7.sh
#!/bin/bash
#
for param in $@; do
echo $param
done
执行命令 ./for_7.sh 1 5 6
,结果:
1
5
6
练习
1、/etc/rc.d/rc3.d
目录下分别有多个以 K
开头和以 S
开头的文件,分别读取每个文件名,以 K
开头的文件输出为文件名加 stop
,以 S
开头的文件输出为文件名加 start
。
#!/bin/bash
#
for line in $(ls /etc/rc.d/rc3.d/ | grep ^[KS]);do
if echo $line | grep ^K &> /dev/null; then
echo "$line stop"
elif echo $line | grep ^S &> /dev/null; then
echo "$line start"
fi
done
2、写一个脚本,使用 ping
命令探测 192.168.2.1-254
之间的主机的在线状态。
#!/bin/bash
#
for line in 192.168.2.{1..254};do
if ping -w1 $line &> /dev/null; then
echo "$line 在线"
else
echo "$line 离线"
fi
done
评论区