-
ver: 1.0
- Blog:博客园 个人
- 本文介绍了Shell常用的结构化语句。
-
数组
- 获取数组所有元素
- 获取数组元素个数
- 数组合并
- 删除数组元素
- 实例
-
选择结构
-
if-else语句
- 基本格式
- if-else
- if-elif-else
- case-in语句
-
循环结构
-
while语句
- until语句
-
for语句
- select-in语句
- break
- continue
-
函数
数组
数组(Array)是若干数据的集合,其中的每一份数据都称为元素(Element)。
Bash只支持一维数组(不支持多维数组),初始化时不需要定义数组大小,理论上可以存放无限量的数据。
与大部分编程语言类似,数组元素的下标由0开始。
Shell数组用括号来表示,元素用"空格"符号分割开。格式如下:
array_name=(ele1 ele2 ele3 ... elen)
Tips:赋值号= 两边不能有空格,必须紧挨着数组名和数组元素。
获取数组中的元素要使用下标[] ,下标可以是一个整数,也可以是一个结果为整数的表达式;当然,下标必须大于等于0。格式如下:
${array_name[index]}
Tips:array_name 是数组名,index 是下标。
Shell是弱类型的,它并不要求所有数组元素的类型必须相同,例如:
arr=(10 24 'ddd' 'ab22' 5)
获取数组所有元素
使用@ 或* 可以获取数组中的所有元素,格式如下:
${array_name[*]}
${array_name[@]}
获取数组元素个数
使用# 来获取数组元素的个数,格式如下:
${#array_name[@]}
${#array_name[*]}
数组合并
数组合并,就是将两个或两个以上的数组合并成一个个数组,格式如下:
array_new=(${array1[@]} ${array2[@]}...${arrayn[@]})
array_new=(${array1[*]} ${array2[*]}...${arrayn[*]})
删除数组元素
使用unset 关键字来删除数组元素,格式如下:
unset array_name[index]
如果不写下标,则代表删除整个数组所有元素,格式如下:
unset array_name
实例
测试ip是否ping通
#!/usr/bin/env bash
# Author: Rohn
# Version: 1.0
# Create Time: 2020/06/13
# Test network connectivity
arr_num=(3 11 25 32 200)
for i in ${arr_num[*]}; do
ip=192.168.110.${i}
ping -c 1 $ip >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "${ip} is ok."
else
echo "${ip} is unreachable."
fi
done
选择结构
Shell中的选择结构(分支结构)有两种形式,分别是 if-else 和case-in 语句,它们都根据命令的退出状态来判断条件是否成立。
if-else语句
基本格式
基本结构格式:
if condition; then
statement(s)
fi
condition 是判断条件,如果condition 成立(返回True),那么then 后边的语句将会被执行;如果 condition不成立(返回False),那么不会执行任何语句。
Tips:最后必须以fi 来闭合,fi 就是if 倒过来拼写。
if-else
如果有两个分支,就可以使用if-else 语句,格式:
if condition; then
statement1
else
statement2
fi
如果condition 成立,那么then 后边的 statement1 语句将会被执行;否则,执行else 后边的statement2 语句。
if-elif-else
当分支比较多时,可以使用if-elif-else 结构,格式:
if condition1; then
statement1
elif condition2;then
statement2
...
else
statementn
fi
Tips:if 和elif 后边都得跟着then 。
语句的执行逻辑:
- 如果
condition1 成立,那么执行statement1 ,如果不成立,则执行elif 语句;
- 如果
elif 语句不成立,则执行else 语句;
case-in语句
当分支较多,且判断条件比较简单时,推荐使用case-in 语句。格式如下:
case expression in
pattern1)
statement1
;;
pattern2)
statement2
;;
...
*)
statementn
esac
-
expression 表示表达式,既可以是一个变量、一个数字、一个字符串,还可以是一个数学计算表达式,或者是命令的执行结果,只要能够得到expression 的值就可以。
-
pattern 表示匹配模式,可以是一个数字、一个字符串,甚至是一个简单的正则表达式。
case 会将expression 的值与 pattern1 、pattern2 ...patternn 逐个进行匹配:
- 如果
expression 和某个模式(比如 pattern2)匹配成功,就会执行这模式(比如 pattern2)后面对应的所有语句(该语句可以有一条,也可以有多条),直到遇见双分号;; 才停止;然后整个case-in 语句就执行完了,程序会跳出整个 case-in 语句,执行esac 后面的其它语句。
- 如果 expression 没有匹配到任何一个模式,那么就执行
*) 后面的语句(* 表示其它所有值),直到遇见双分号;; 或者esac 才结束。*) 相当于多个if 分支语句中最后的else 部分。
Tips:分支*) 并不是什么语法规定,它只是一个正则表达式,* 表示任意字符串,所以不管expression 的值是什么,*) 总能匹配成功。因此,可以没有*) 部分,如果expression 没有匹配到任何一个模式,那么就不执行任何操作。
除最后一个分支外(这个分支可以是普通分支,也可以是*) 分支),其它的每个分支都必须以;; 结尾,;; 代表一个分支的结束,不写的话会有语法错误。最后一个分支可以写;; ,也可以不写,因为无论如何,执行到esac 都会结束整个case-in 语句。
case-in 的pattern 部分支持简单的正则表达式,具体来说,可以使用以下几种格式:
格式 |
说明 |
* |
表示任意字符串。 |
[abc] |
表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。 |
[m-n] |
表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。 |
| |
表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 "abc" 或者 "xyz"。 |
用;; &终止每个条件块,例如:
read -n 1 -p "Type a character > "
echo
case $REPLY in
[[:upper:]]) echo "'$REPLY' is upper case." ;;&
[[:lower:]]) echo "'$REPLY' is lower case." ;;&
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;&
[[:digit:]]) echo "'$REPLY' is a digit." ;;&
[[:graph:]]) echo "'$REPLY' is a visible character." ;;&
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;;&
[[:space:]]) echo "'$REPLY' is a whitespace character." ;;&
[[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;&
esac
输出结果如下:
Type a character > a
'a' is lower case.
'a' is alphabetic.
'a' is a visible character.
'a' is a hexadecimal digit.
循环结构
循环结构语句大致分为4种:
while语句
当条件满足时,while 重复地执行一组语句,当条件不满足时,就退出while 循环。格式如下:
while condition; do
statements
done
执行流程如下:
- 先对
condition 进行判断,如果该条件成立,就进入循环,执while 循环体中的语句,也就是do 和done 之间的语句。这样就完成了一次循环。
- 每一次执行到
done 的时候都会重新判断condition 是否成立,如果成立,就进入下一次循环,继续执行do 和done 之间的语句,如果不成立,就结束整个while 循环,执行done 后面的其它Shell 代码。
- 如果一开始
condition 就不成立,那么程序就不会进入循环体。
死循环
格式一:
while true; do
statements
done
格式二:
while [ 1 ]; do
statements
done
until语句
until 循环当判断条件不成立时才进行循环,一旦判断条件成立,就终止循环。
until condition; do
statements
done
until 循环的执行流程为:
- 先对
condition 进行判断,如果该条件不成立,就进入循环,执行until 循环体中的语句(do 和done 之间的语句),这样就完成了一次循环。
- 每一次执行到
done 的时候都会重新判断condition 是否成立,如果不成立,就进入下一次循环,继续执行循环体中的语句,如果成立,就结束整个 until 循环,执行done 后面的其它Shell 代码。
for语句
C语言风格的 for 循环
格式如下:
for((exp1; exp2; exp3)); do
statements
done
exp1 、exp2 、exp3 是三个表达式,其中exp2 是判断条件,for 循环根据exp2 的结果来决定是否继续下一次循环;
它的运行过程为:
- 先执行
exp1 。
- 再执行
exp2 ,如果它的判断结果是成立的,则执行循环体中的语句,否则结束整个for 循环。
- 执行完循环体后再执行
exp3 。
- 重复执行2、3步骤,直到
exp2 的判断结果不成立,就结束循环。
for-in循环
格式如下:
for variable in value_list; do
statements
done
variable 表示变量,value_list 表示取值列表。
每次循环都会从value_list 中取出一个值赋给变量 variable ,然后进入循环体(do 和done 之间的部分),执行循环体中的statements 。直到取完value_list 中的所有值,循环就结束了。
value_list :
for i in 1 2 3 'dd';do echo $i;done
# 求1到10的和
sum=0
for i in {1..10}; do
sum=$((sum+i))
done
echo $sum
# 求100以内偶数的和
for i in $(seq 2 2 100); do
sum=$((sum+i))
done
echo $sum
# 打印当前路径.log结尾的文件
for i in *.log; do echo $i;done
Tips:若当前路径无.log结尾的文件,则会打印*.log
for i in $@; do
sum=$((sum+i))
done
echo $sum
select-in语句
select-in 循环用来增强交互性,它可以显示出带编号的菜单,用户输入不同的编号就可以选择不同的菜单,并执行不同的功能,非常适合终端(Terminal)这样的交互场景。格式如下:
select variable in value_list; do
statements
done
variable 表示变量,value_list 表示取值列表。
例如:
echo "选择你要学习的科目:"
select i in 'Linux' 'Python' 'Java' 'C++' 'PHP'; do
echo "你选择了${i}。"
done
结果如下:
选择你要学习的科目:
1) Linux
2) Python
3) Java
4) C++
5) PHP
#? 5
你选择了PHP。
#? 2
你选择了Python。
#? 666
你选择了。
Tips:select 是死循环,输入空值或者输入的值无效,都不会结束循环,只有遇到break 语句,或者按下Ctrl+D 组合键才能结束循环。
例如:
echo "选择你要学习的科目:"
select i in 'Linux' 'Python' 'Java' 'C++' 'PHP'; do
echo "你选择了${i}。"
break
done
结果如下:
选择你要学习的科目:
1) Linux
2) Python
3) Java
4) C++
5) PHP
#? 5
你选择了PHP。
select-in 语句常和case-in 语句一起使用。
break
格式如下:
break n
n 表示跳出循环的层数,如果省略n,则表示跳出当前。
continue
格式如下:
continue n
n 表示循环的层数:
- 如果省略
n ,则表示continue 只对当前层次的循环语句有效,遇到continue 会跳过本次循环,忽略本次循环的剩余代码,直接进入下一次循环。
- 如果带上
n ,比如n 的值为2,那么continue 对内层和外层循环语句都有效,不但内层会跳过本次循环,外层也会跳过本次循环,其效果相当于内层循环和外层循环同时执行了不带n 的continue 。
与break 的区别:
-
break 用来结束当前整个循环;
-
continue 用来结束本次循环,直接跳到下一次循环,如果循环条件成立,还会继续循环;
函数
函数的本质是一段可以重复使用的脚本代码,这段代码被提前编写好了,放在了指定的位置,使用时直接调取即可。
函数定义
格式如下:
function func_name() {
statements
[return value]
}
Tips:关键词function 是可选的,但必须在一个项目中保持一致。
说明:
-
function 是Shell中的关键字,专门用来定义函数,可以不写,但要求在整个项目脚本中保持一致,即统一不写或都写;
-
func_name 是函数名,按照约定规范,函数名后面必须带上() ;
-
statements 是函数要执行的代码,也就是一组语句;
-
return value 表示函数的返回值,其中return 是Shell关键字,专门用在函数中返回一个值;这一部分可以写也可以不写。
函数调用
调用Shell函数时可以给它传递参数,也可以不传递。如果不传递参数,直接给出函数名字即可,格式如下:
func_name
如果传递参数,那么多个参数之间以空格分隔:
func_name param1 param2 param3...
Tips:不管是哪种调用方式,函数名字后面都不需要带()
函数参数
函数参数是Shell 位置参数的一种,在函数内部可以使用$n 来接收,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。
除了$n ,还有另外三个比较重要的变量:
-
$# 可以获取传递的参数的个数;
-
$@ 或者$* 可以一次性获取所有的参数
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|