shell中提供了if
、case
进行分支控制,下面将介绍shell中分支使用。
命令格式:
# 样式1
if command
then
commands
fi
# 样式2,使用;将then写到与if同行
if command; then
commands
fi
if
会判断后面跟着的command的退出状态码
,如果返回0,则会执行then后面的commands。
示例:
## 退出状态码为0示例 :
# 创建if脚本,内容如下
[root@vm14 shell]# cat if.sh
#!/bin/bash
# 测试if语句
if pwd
then
echo 'It works'
fi
# 执行if.sh,因为命令pwd成功执行(退出状态码:0),因此then后面的命令被执行
[root@vm14 shell]# sh if.sh
/root/shell
It works
# 退出状态码非0示例
[root@vm14 shell]# cat if_error.sh
#!/bin/bash
# 测试一个错误命令
if BadCmd
then
echo 'It works'
fi
echo 'if finish'
# 运行脚本,因为BadCmd不是一个命令,返回状态码非0,因此then后面的命名未被执行
[root@vm14 shell]# sh if_error.sh
if_error.sh:行3: BadCmd: 未找到命令
if finish
命令格式:
# 样式1
if command
then
commands
else
commonds
fi
# 样式2,使用;将then写到与if同行
if command; then
commands
else
commonds
fi
当if
后面的command的退出状态码为0
时,执行then
后面的commands;非0
时,执行else
后面的commonds。
示例:
[root@vm14 shell]# cat if_else.sh
#!/bin/bash
# 测试if-then-else
testuser=root
if grep $testuser /etc/passwd ; then
echo '第一条命令'
echo '第二条命令'
ls -a /root/.b*
else
echo '没有这个用户!'
fi
[root@vm14 shell]# sh if_else.sh
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
第一条命令
第二条命令
/root/.bash_history /root/.bash_logout /root/.bash_profile /root/.bashrc
命令格式:
# 样式1
if command1
then
commands
elif command2
then
commonds
else
commonds
fi
# 样式2,使用;将then写到与if同行
if command1; then
commands
elif command2; then
commands
else
commonds
fi
示例:
[root@vm14 shell]# cat if_elif.sh
#!/bin/bash
# 测试嵌套if
var1=5
if [ $var1 -lt 5 ]; then
echo "$var1 小于5"
elif [ $var1 -eq 5 ]; then
echo "$var1 等于5"
else
echo "$var1 大于5"
fi
[root@vm14 shell]# sh if_elif.sh
5 等于5
命令格式:
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
case命令检测变量variable的值,如果是pattern1或pattern2,则执行commands1;如果变量variable是pattern3,则执行commands2;否则执行default commands。
示例:
#!/bin/bash
# 测试case命令,如果第一个参数是start或stop,输出start or stop;
# 如果第一个参数是restart,输出restart;否则输出other
par=$1
case $par in
start | stop ) echo 'start or stop';;
restart ) echo 'restart' ;;
*) echo 'other' ;;
esac
# 当第一个参数是start时,输出start or stop
[root@vm14 shell]# sh case.sh start
start or stop
# 第一个参数是restart时,输出restart
[root@vm14 shell]# sh case.sh restart
restart
# 第一个参数是hello,输出other
[root@vm14 shell]# sh case.sh hello
other
命令格式:
[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]
bash shell中的循环包括for
、while
、until
,下面将分别介绍他们。
命令格式:
# 样式1
for var in list
do
commands
done
# 样式2,使用;将do写到与for同行
for var in list; do
commands
done
示例:
#@@@@@ 示例1,当编程语言有空格时,用双引号进行处理,否则会当两个名称处理
[root@vm14 shell13]# cat for.sh
#!/bin/bash
# for命令测试
for name in java "bash shell"
do
echo 编程语言:$name
done
echo 命令结束后name会保存最后一个语言:$name
[root@vm14 shell13]# sh for.sh
编程语言:java
编程语言:bash shell
命令结束后name会保存最后一个语言:bash shell
#@@@@@ 示例2,变量中的空格处理
[root@vm14 shell13]# cat for_space.sh
#!/bin/bash
# 变量中空格处理
echo 切分异常情况:
str="java 'bash shell'"
for s in $str; do
echo $s
done
echo 方式1,使用eval:
eval "for s in $str; do echo \$s; done"
echo 方式2,使用数组:
arr=(java "bash shell")
for name in "${arr[@]}"; do
echo $name
done
[root@vm14 shell13]# sh for_space.sh
切分异常情况:
java
'bash
shell'
方式1,使用eval:
java
bash shell
方式2,使用数组:
java
bash shell
#@@@@@ 示例3 从命令中取值
# 创建names文件,存放待读取数据
[root@vm14 shell13]# cat names
java
bash shell
# 读取names文件中的数据,并循环输出
[root@vm14 shell13]# cat for_cmd.sh
#!/bin/bash
# for从命令中取值测试
file=names
# 使用默认IFS(internal field separator):空格、制表符、换行符
for name in $(cat $file);do
echo 默认IFS:$name
done
# 修改IFS,仅使用换行符
IFS_OLD=$IFS # 存储原IFS
IFS=$'\n'
for name in $(cat $file); do
echo 换行符IFS:$name
done
IFS=$IFS_OLD # 恢复IFS
[root@vm14 shell13]# sh for_cmd.sh
默认IFS:java
默认IFS:bash
默认IFS:shell
换行符IFS:java
换行符IFS:bash shell
#@@@@@ 示例4,使用通配符读取文件列表
[root@vm14 shell13]# cat for_dir.sh
#!/bin/bash
# 使用通配符读取目录下文件,可以传递多个通配符
for file in /home/* /root/*cfg
do
if [ -d "$file" ];then
echo "$file 是目录"
elif [ -f "$file" ];then
echo "$file 是文件"
fi
done
[root@vm14 shell13]# sh for_dir.sh
/home/dft 是目录
/home/test1 是目录
/home/test2 是目录
/root/anaconda-ks.cfg 是文件
C语言风格的for循环与bash shell差异点:
命令格式:
# 样式1
for (( variable assignment ; condition ; iteration process ))
do
commands
done
# 样式2,使用;将do写到与for同行
for (( variable assignment ; condition ; iteration process )); do
commands
done
示例:
#@@@@@ 示例1,通过for循环输出0-9
[root@vm14 shell13]# cat cfor.sh
#!/bin/bash
# 测试C风格for循环
for (( a=0; a<10 ;a++ ))
do
echo 当前数字$a
done
[root@vm14 shell13]# sh cfor.sh
当前数字0
当前数字1
当前数字2
当前数字3
当前数字4
当前数字5
当前数字6
当前数字7
当前数字8
当前数字9
# @@@@@ 示例2,多变量for循环
[root@vm14 shell13]# cat cfor2.sh
#!/bin/bash
# 测试C风格for循环
for (( a=0,b=9; a<10 ;a++,b-- ))
do
echo 当前数字a:$a , b:$b
done
[root@vm14 shell13]# sh cfor2.sh
当前数字a:0 , b:9
当前数字a:1 , b:8
当前数字a:2 , b:7
当前数字a:3 , b:6
当前数字a:4 , b:5
当前数字a:5 , b:4
当前数字a:6 , b:3
当前数字a:7 , b:2
当前数字a:8 , b:1
当前数字a:9 , b:0
[root@an01 ~]# cat forin.sh
for i in {1..10}
do
echo $i
done
[root@an01 ~]# sh forin.sh
1
2
3
4
5
6
7
8
9
10
while: 循环检测测试条件的状态码,如果为0,则执行do-done间命令,否则退出循环。
命令格式:
# 样式1
while test command
do
other commands
done
# 样式2,使用;将do写到与while同行
while test command; do
other commands
done
示例:
#@@@@@ 示例1,当变量var1大于0时,输出$var1,并进行减一操作
[root@vm14 shell13]# cat while.sh
#!/bin/bash
# 测试while命令
var1=10
while [ $var1 -gt 0 ]; do
echo $var1
var1=$[$var1-1]
done
[root@vm14 shell13]# sh while.sh
10
9
8
7
6
5
4
3
2
1
#@@@@@ 示例2, 当while后有多个命令时,以最后一个命令的退出状态码为退出循环条件
[root@vm14 shell13]# cat while2.sh
#!/bin/bash
# 测试while命令
var1=5
while echo $var1 ; [ $var1 -gt 0 ]; do
echo "in loop"
var1=$[$var1-1]
done
[root@vm14 shell13]# sh while2.sh
5
in loop
4
in loop
3
in loop
2
in loop
1
in loop
0
until命令和while命令工作的方式完全相反
。 until命令要求你指定一个通常返回非零退出状态码的测试命令。
命令格式:
# 样式1
until test commands
do
other commands
done
# 样式2,使用;将do写到与until同行
until test commands; do
other commands
done
示例:
#@@@@@ 示例1,一直对var1进行减25操作,直到var1等于0为止
[root@vm14 shell13]# cat until.sh
#!/bin/bash
# until命令测试
var1=100
until [ $var1 -eq 0 ]; do
echo $var1
var1=$[$var1-25]
done
[root@vm14 shell13]# sh until.sh
100
75
50
25
## untul有多个测试命令时,只有在最后一个命令成立时停止
bash shell提供了break
、continue
两个命令来跳出循环,break为跳出循环,continue为跳出本次循环。
示例:
#@@@@@ 示例1,使用break跳出for循环
[root@vm14 shell13]# cat break.sh
#!/bin/bash
# 使用break跳出for循环
for var1 in 1 2 3 4 5 6 7 8 9 10; do
if [ $var1 -eq 5 ]; then
break
fi
echo "当前数字: $var1"
done
echo "循环结束"
[root@vm14 shell13]# sh break.sh
当前数字: 1
当前数字: 2
当前数字: 3
当前数字: 4
循环结束
#@@@@@ 示例2,使用break跳出外层循环
[root@vm14 shell13]# cat break2.sh
#!/bin/bash
# 使用break跳出外循环
for (( a=0;a<100;a++ ));do
echo 外循环a:$a
for ((b=0;b<10;b++));do
if [ $b -gt 2 ]; then
# break n
# 其中n指定了要跳出的循环层级。默认情况下, n为1,表明跳出的是当前的循环。
# 如果你将n设为2, break命令就会停止下一级的外部循环。
break 2
fi
echo 内循环b:$b
done
done
echo "循环结束"
[root@vm14 shell13]# sh break2.sh
外循环a:0
内循环b:0
内循环b:1
内循环b:2
循环结束
示例:
#@@@@@ 示例1,如果$va1大于2且小于8,则中断本次循环
[root@vm14 shell13]# cat continue.sh
#!/bin/bash
# 使用continue跳出本次for循环
for var1 in 1 2 3 4 5 6 7 8 9 10; do
if [ $var1 -gt 2 ] && [ $var1 -lt 8 ]; then
continue
fi
echo "当前数字: $var1"
done
echo "循环结束"
[root@vm14 shell13]# sh continue.sh
当前数字: 1
当前数字: 2
当前数字: 8
当前数字: 9
当前数字: 10
循环结束
#@@@@@ 示例2,中断外层循环
[root@vm14 shell13]# cat continue2.sh
#!/bin/bash
# 使用break跳出外循环
for (( a=0;a<5;a++ ));do
echo 外循环a:$a
for ((b=0;b<2;b++));do
if [ $a -gt 2 ]; then
# continue n
# 其中n指定了要跳出的循环层级。默认情况下, n为1,表明跳出的是当前的循环。
# 如果你将n设为2,continue命令就会停止下一级的本次外部循环。
continue 2
fi
echo 内循环b:$b
done
done
echo "循环结束"
[root@vm14 shell13]# sh continue2.sh
外循环a:0
内循环b:0
内循环b:1
外循环a:1
内循环b:0
内循环b:1
外循环a:2
内循环b:0
内循环b:1
外循环a:3
外循环a:4
循环结束