首页 > 代码库 > 《学习bash》笔记--流程控制
《学习bash》笔记--流程控制
bash支持下述流程控制结构:
if/else:如果某条件为真/假,执行一个执行列表。
for:执行一个语句列表固定次数。
while:当某条件为真时重复执行某语句列表
until:重复执行某语句列表直至某条件为真。
case:依据一个变量取值执行几个语句列表中的一个。
select:允许用户从一个菜单的可选列表中选择一个。
1.if/else
最简单的流程控制结构类型时嵌入在bash的if语句中的条件语句。当选择做或者不做某件事情或者依据条件表达式的真或者假
从数量不多的几个事情里选择一个进行操作时可以使用条件语句。条件语句测试包含shell变量的值,文字字符特征,命令是否
成功及其他因素。
if结构语法如下:
if condition
then
statements
[elif condition
then statements]
[else
statements]
fi
1.1退出状态和返回
if检查if关键字后的列表中最后一个语句的退出状态。该列表通常指示一个语句,如果状态为0,则条件评估为真,如果是其他,
条件为假。该情况对elif语句下的每个条件也适用。
例如a.sh的内容如下:
if cd $1;
then
echo "OK"
else
echo "NG"
fi
then
echo "OK"
else
echo "NG"
fi
执行结果:
#./a.sh 1
./a.sh: line 1: cd: 1: No such file or directory
NG
./a.sh: line 1: cd: 1: No such file or directory
NG
# ./a.sh /dev
OK
OK
对于脚本中分号,是用来隔断每个语法关键字或命令的。上面的格式分号写与不写效果一样,但是如果写成如下:
if cd $1;then echo "OK";else echo "NG";fi
不写分号就会出错。
if cd $1;then echo "OK";else echo "NG";fi
不写分号就会出错。
需要的第二个特性时语句return N,它使得包含它的函数以状态N退出。N实际上可选,其默认为最后一个命令的退出状态,没有
以return语句结束的函数将返回最后一个语句返回的状态。return只能用在函数以及使用source执行的shell脚本内,相比较,语句
exit N将退出整个脚本,而不管其嵌套在函数内多少层。
1.2.组合退出状态
bash允许你逻辑上组合退出状态,这样就可以一次测试多个内容。
语法 statement1 && statement2意思时执行statement1,如果其退出状态为0,则执行statement2。
语法statement1 || statement2刚好相反:执行statement1,如果其退出状态非0,则执行statement2。
1.3.条件测试
shell使用[......]结构提供了测试各种条件的方式。可以使用该结构检验一个文件的各种属性,或比较两个文件哪个更新,以及对字符
串进行比较。
[#condition#]返回一个退出状态,给出condition是否为真的信息。[]中的空格是必须的。
1.3.1.字符串比较
str1 = str2
则str1匹配str2
str1 != str2
str1不匹配str2
str1 \< str2
str1小于str2
str1 \> str2
str1大于str2
-n str1
str1为非null,即长度大于0. 也可以直接使用[ “$str1” ]。
-z str1
str1为null,即长度为0.
其中注意的是,使用<,>时需要转义,而且比较符两边的空格不能少,不然会被认为是一个字符串。
例如a.sh内容如下:
str1="132"
str2="125"
if [ $str1 \> $str2 ]
str2="125"
if [ $str1 \> $str2 ]
then
echo "str1 is bigger than str2"
else
echo "str1 is not bigger than str2"
fi
echo "str1 is bigger than str2"
else
echo "str1 is not bigger than str2"
fi
执行结果:
str1 is bigger than str2.
脚本依次比较字符串中的字符的ascii码来判断大小。
1.3.2.文件属性检查
-d file
file存在并且为一个目录。
-e file
file存在。
-f file
file存在并且为一常规文件(亦即不是一个目录或其他特殊类型文件)
-r file
对文件有读权限
-s file
文件存在并且非空
-w file
对file有写权限
-x file
对file有可执行权限,如果为目录,则有目录搜索权限
-O file
你是file的所有者
-G file file组ID匹配你的ID(如果你在多个组中,则匹配其中一个)
file1 -nt file2
file存在并且为一个目录。
-e file
file存在。
-f file
file存在并且为一常规文件(亦即不是一个目录或其他特殊类型文件)
-r file
对文件有读权限
-s file
文件存在并且非空
-w file
对file有写权限
-x file
对file有可执行权限,如果为目录,则有目录搜索权限
-O file
你是file的所有者
-G file file组ID匹配你的ID(如果你在多个组中,则匹配其中一个)
file1 -nt file2
file1比file2新
file1 -ot file2
file1比file2旧
file1 -ot file2
file1比file2旧
也可以在条件表达式前加上!符号否定其真值,这样只有表达式为假时,!expr值才为真。另外,可以通过使用圆括号用斜线转义
防止shell对其进行特殊处理将值分组或使用没有介绍过的两个逻辑操作符:-a(AND)和-o(OR),进而实现条件操作符的复杂
逻辑表达式。
例如:
if[ \(-n $dirname1\) -a \(-n $dirname2\) ] then
只有dirname1和dirname2都不为空时才执行。
1.3.3.整数条件
shell还提供算数测试集合。他们比较字符串的数字值。-lt 小于
-le 小于等于
-eq 等于
-ge 大于等于
-gt 大于
-ne 不等于
2.for
for循环允许你重复一段代码固定次数,在循环代码执行期间,一个称为循环变量的特殊变量被赋予了不同的值;这样每个
循环的功能就有了细微的差别。
for循环很适合处理命令行上的参数以及文件集,for结构的语法如下:
循环的功能就有了细微的差别。
for循环很适合处理命令行上的参数以及文件集,for结构的语法如下:
for name [in list]
do
statements
done
list为名称列表,如果in list被省略,列表默认为"$@",即命令行参数的引用列表。
例如a.sh的内容如下:
for folder in "$@"
do
echo -e "\t$folder"
done
do
echo -e "\t$folder"
done
执行结果如下:
$ ./a.sh a b c
a
b
c
a
b
c
其中echo的-e选项使tab识别被转义的格式化字符,这里为/t.顺便提下-n选项,该选项令echo在结尾不打印LINEFEED。
3.case
case的结构使你依据可包含通配符的模式测试字符串,时你以一种更精确的方式表示一系列if-then-else类型的语句。
case的语法如下:
case expression in
pattern1)
statements;;
pattern2)
statements;;
esac
任何pattern实际上都可以由管道字符|分隔的几个模式组成,如果expression匹配其中一个模式。其相应语句被执行。如果存在
几个管道字符分隔的模式,表达式会尝试匹配其中的每一个以使相应语句被执行。模式被按次序检测,直至成功匹配。如果每一个
都匹配不上,则不执行任何动作。
需要注意的是,statements以两个分号结尾。
例如a.sh的内容如下:
for filename in "$@"
do
case $filename in
*.doc|*.docx)
echo "$filename:doc file";;
*.txt)
echo "$filename:txt file";;
*)
echo "$filename:unknown file";;
esac
done
do
case $filename in
*.doc|*.docx)
echo "$filename:doc file";;
*.txt)
echo "$filename:txt file";;
*)
echo "$filename:unknown file";;
esac
done
执行结果:
$ ./a.sh a.txt b.doc c.docx d.pdf
a.txt:txt file
b.doc:doc file
c.docx:doc file
d.pdf:unknown file
a.txt:txt file
b.doc:doc file
c.docx:doc file
d.pdf:unknown file
4.select
select使你可以很容易地生成菜单。其语法:
select name [in list]
do
statements
done
像for一样,你可以省略in list,被默认为“$@”,即引用的命令行参数列表,select功能如下:
1.生成列表内每一条目的逃单,并且将之格式化,使其每一个选择对应一个数字。
2.提示用户输入数字。
3.将已选择条目保存在变量name内,已选择编号保存在内置变量REPLY中。
4.执行条目内的语句。
5.无限循环该过程。
break时退出select循环的chang
例如a.sh的内容如下:
PS3="directory?"
select folder in "$@"
do
echo "the num is $REPLY,$folder is selected"
break
done
执行结果:
$ ./a.sh a b c d
1) a
2) b
3) c
4) d
directory?1
the num is 1,a is selected
select folder in "$@"
do
echo "the num is $REPLY,$folder is selected"
break
done
执行结果:
$ ./a.sh a b c d
1) a
2) b
3) c
4) d
directory?1
the num is 1,a is selected
5.while和until
while的语法如下:
while 条件测试
do
执行命令
done
do
执行命令
done
1
2
3
4
5
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。