注:前言、目录见 https://blog.csdn.net/qq_44220418/article/details/108428971
Tips:其实主要也就是把菜鸟教程上的shell编程教程过了一遍,自己探索了一部分,记录了自己的所得与理解
一、注释
#单行注释
:<<EOF
多行注释
多行注释
多行注释
EOF
二、输出
1、echo
命令
可以使用echo
命令输出相关内容(字符串,可以是双引号字符串、单引号字符串、命令的执行结果……)
str="hello"
echo 'hello world' # hello world
echo "${str} world" # hello world
echo "\"${str} world\"" # "hello world"
echo `ls | wc -l` # 1
像是\"
这样的转义,echo
命令可以直接识别
如果要识别\n
、\c
这样的特殊字符,需要为echo
命令加上参数-e
echo -e "123\ntest"
也可以配合重定向符>
、>>
将输出内容输出到文件
echo -e "1\n2\n3\n45" > 1.txt
2、printf
命令
printf
命令模仿 C 程序库里的printf()
函数
一般格式如下:
printf "格式控制字符串" [参数列表]
和C语言一样,printf
命令支持如下格式替代符
格式替代符 | 说明 | 示例结果 |
---|---|---|
%d | int | |
%ld | long | |
%lld | long long | |
%o | 八进制整数 | |
%x | 十六进制整数(小写) | 7f |
%X | 十六进制整数 (大写) | 7F |
%#x | 十六进制整数(带前缀小写) | 0x7f |
%#X | 十六进制整数(带前缀大写) | 0X7F |
%f | float | |
%lf | double | |
%e | 指数形式浮点数 | 1.565600e+02 |
%c | char | |
%s | 字符串 |
注:
\qquad
格式替代符都以%
打头,要对%
进行转义的话,应使用%%
而不是\%
还有以下一些特殊的控制
格式字符串 | 说明 | 示例 |
---|---|---|
%.mf | m 是一个整数,表示输出实数时小数点后保留m 位 | %.5f |
%-md | m 是一个整数,表示输出整数时至少占m 个字符的位置,并左对齐,类似的也可以用%-ms 、%-mf | %-5d |
%md | m 是一个整数,表示输出整数时至少占m 个字符的位置,并右对齐,类似的也可以用%ms 、%mf | %5d |
这些特殊控制是可以组合使用的,如:%-8.6f
代表输出一个至少占8个字符后左对齐的、保留到小数点后6位的实数
下面是常用的特殊字符
特殊字符 | 说明 | 示例 |
---|---|---|
\a | 警告字符,通常为ASCII的BEL字符 | |
\b | 后退 | |
\c | 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效) 而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 | |
\f | 换页 | |
\n | 换行 | |
\r | 回车 | |
\t | 水平制表符 | |
\v | 垂直制表符 | |
\ddd | d 代表一个
0
∼
7
0 \sim 7
0∼7的数字(或者缺省) | '\65' 就相当于ASCII编码为53 的字符'5' |
\0ddd | d 代表一个
0
∼
7
0 \sim 7
0∼7的数字(或者缺省) | '\0065' 就相当于ASCII编码为53 的字符'5' |
\xddd | d 代表一个
0
∼
f
0 \sim \text{f}\;
0∼f的数字(或者缺省) | '\x56' 就相当于ASCII编码为86 的字符'V' |
# 引号的区别
printf "%d\n" 566 # 556
printf '%d\n' 556 # 556
printf %d\n 556 # 556n(不换行)
# 格式控制
printf "|%8.2f|%-6d|%-5s|\n" 3.141 123 ab # | 3.14|123 |ab |
# 缺省值
printf "%d %d %d\n" 12 3 # 12 3 0
# 多余参数
printf "%d %d " 123 456 789 # 123 456 789 0 (不换行)
注:
\qquad
① 单引号、双引号没有区别;不加引号时格式替代符可以正常输出,但是像\n
这样的转义字符无法正常输出
\qquad
② 缺少的参数
\qquad\qquad
%c
、%s
用空字符、空串填充
\qquad\qquad
%d
、%ld
、%lld
用0
填充
\qquad\qquad
%f
、%lf
用0.000000
填充
\qquad\qquad
%e
用0.000000e+00
填充
\qquad
③ 多余的参数会重复使用前面的格式字符串继续进行输出(多余不足时用缺省填充)
三、变量
1、定义
定义变量时,类似Python,可以直接通过赋值来定义变量,不需要加$
符号
变量名的命名须遵循如下规则:
- 命名只能使用英文字母、数字、下划线,首个字符不能以数字开头
- 中间不能有空格,可以使用下划线(_)
- 不能使用标点符号
- 不能使用bash里的关键字(可用help命令查看保留关键字)
2、使用
使用变量时,通过$
符号来进行使用,形如$a
、${a}
在执行时,系统会将其替换为其相应的值,因此定义变量后再次赋值仍不需要用$
符,像定义时一样赋值即可,可以理解为重定义
a=2
${a}=3 # (错误的重新赋值) 报错:2=3: command not found...
a=3 # (正确的重新赋值)
通过在变量名前加上前缀readonly
可以将变量定义为只读变量
readonly a=2
b=3
readonly b
3、删除
使用unset
删除某个变量
a=2
unset a
四、字符串
1、表示
单引号字符串
\qquad
单引号字符串的限制:
\qquad\qquad
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
\qquad\qquad
单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用
双引号字符串
\qquad
双引号字符串的优点:
\qquad\qquad
双引号里可以有变量
\qquad\qquad
双引号里可以出现转义字符
2、拼接
可以直接将一个字符串写在另一个字符串的后面完成拼接
echo '12341''12421414' # 1234112421414
echo "12341""12421414" # 1234112421414
a=2
echo "a"$a"a" # a2a
3、长度
通过#
获取字符串长度
str="adc"
echo ${#str} # 3
4、截子串
通过:n
截取子串(从下标为n
的字符开始截取到最后)
通过:n:m
截取子串(从下标为n
的字符开始往后截取m
个字符)
str="0123456789"
echo ${str:2:4} # 2345
echo ${str:2} # 23456789
5、查位置
通过expr index "$str" 要查找的字符们
来查找这些字符在字符串str
中第一次出现的位置(是从1
开始的编号,而不是从0
开始的索引)
str="abcd1234"
echo `expr index "${str}" a` # 1
echo `expr index "${str}" 1` # 5
echo `expr index "${str}" c1` # 3
五、数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小
1、定义
用括号声明数组
# 形式1
数组名=(值1 值2 ... 值n)
# 形式2
数组名=(
值1
值2
...
值n
)
也可以通过定义数组的分量来定义数组(下标可以不连续,下标范围无限制)
数组名[下标1]=值1
数组名[下标2]=值2
数组名[下标n]=值n
2、取元素
在数组中取单个元素的格式如下
# 获取数组中指定下标的元素
${数组名[下标]}
# 获取数组中首元素
${数组名}
注:直接访问数组名并不是获得全部元素,而是获得数组下标为0的元素
在数组中取全部元素的格式如下
${数组名[@]}
${数组名[*]}
Tips:用@
和用*
只有在被双引号引用时才有区别,可以参考博客 https://blog.csdn.net/asty9000/article/details/86681517
示例
arr=(1 23 456 7890)
echo ${arr} # 1
echo ${arr[2]} # 456
echo ${arr[@]} # 1 23 456 7890)
3、长度
使用#
取长度(可以取数组的长度,也可以取元素的长度)
arr=(1 23 456 78)
echo ${#arr} # 1
echo ${#arr[0]} # 1
echo ${#arr[2]} # 3
echo ${#arr[@]} # 4
六、运行与传参
1、运行
编写完sh脚本后,使用chmod
命令为其添加可执行权限,然后指定sh脚本的位置,运行
chmod a+x test.sh
./test
2、运行传参
运行sh脚本前,是可以传入参数的
./test 1 2 34 5678
以上述传入的参数为例,解释一下处理参数的特殊字符
参数处理 | 说明 | 在上述示例中 |
---|---|---|
$n | 传入脚本的第n个参数 | 比如$1 、$2 就对应了传入脚本的第1个参数(1)、第2个参数(2) |
$# | 传入脚本的参数个数 | 4 |
$* | 传入脚本传递的所有参数(以单字符串方式)"$*" 相当于"$1 $2 ... $n" (一个元素) | 1 2 34 5678 |
$@ | 传入脚本传递的所有参数(以多字符串方式)"$@" 相当于"$1" "$2" ... "$n" (一堆元素) | 1 2 34 5678 |
$$ | 脚本运行的当前进程ID号 | |
$! | 后台运行的最后一个进程的ID号 | |
$- | 显示Shell使用的当前选项,与set 命令功能相同 | |
$? | 显示最后命令的退出状态 { 0 没 有 错 误 其 他 有 错 误 \begin{cases}0 & 没有错误\\ 其他 & 有错误\end{cases} {0其他没有错误有错误 |
七、运算符
1、算术运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如awk
和expr
,expr
最常用
expr
是一款表达式计算工具,使用它能完成表达式的求值操作
a=21
b=5
echo `expr ${a} + ${b}` # 26
echo `expr ${a} - ${b}` # 16
echo `expr ${a} \* ${b}` # 105
echo `expr ${a} / ${b}` # 4
echo `expr ${a} % ${b}` # 1
echo $((a + b)) # 26
echo $((a - b)) # 16
echo $((a * b)) # 105
echo $((a / b)) # 4
echo $((a % b)) # 1
Tips:使用以下形式快速计算表达式,并且不需要使用$
符对变量进行使用
\qquad
可以使用$((表达式))
直接使用+
、-
、++
、--
等进行算术运算(有时候加上$
后,执行表达式后会提示命令不存在)
\qquad
可以使用$[表达式]
直接使用+
、-
、++
、--
等进行算术运算
\qquad
可以使用let 表达式
直接使用+
、-
、++
、--
等进行算术运算
其中
\qquad
$((表达式))
和$[表达式]
加$
会把运算返回的结果当成命令,有时候会提示命令XXX不存在
\qquad
不加$
的话,((表达式))
可以无误执行,但[表达式]
不行
\qquad
只是对变量进行操作的话,建议使用let 表达式
的写法
一些特殊的表达式用法,推荐这篇博客 https://blog.csdn.net/x1269778817/article/details/46535729
2、关系运算符
(1).条件表达式
这些概念是我的理解,用词等不一定很官方、很专业
条件表达式返回逻辑真true
/ 逻辑假false
条件语句是条件表达式的一部分,可以说,给条件语句加上适当的格式就成了条件表达式
e
g
:
eg:
eg:$a -ge 100
是条件语句,[ $a -ge 100 ]
是条件表达式
像是[ 条件语句 ]
这样的格式为条件表达式(注意[]
两边必须有空格)
条件表达式似乎有很多种,可以是[ 条件语句 ]
、[[ 条件语句 ]]
、(( 条件语句 ))
、test 条件语句
,用的比较多的就是[ 条件语句 ]
了
至于它们有什么区别,下面 [[ ]] 和 [ ] 的区别 会讲到
(2).关系运算符
关系运算符,大多以-
开头,我理解为整数关系运算符,如大于-gt
、小于等于-le
……
这些只能用作整数(或整数字符串)间比较
运算符 | 说明 | 使用示例 |
---|---|---|
-eq | 相等 | [ $a -eq $b ] |
-ne | 不等 | [ $a -ne $b ] |
-gt | 大于 | [ $a -gt $b ] |
-lt | 小于 | [ $a -lt $b ] |
-ge | 大于等于 | [ $a -ge $b ] |
-le | 小于等于 | [ $a -le $b ] |
还有两个运算符==
和!=
,我也将它们归到关系运算符中,它们可以比较的东西很多
运算符 | 说明 | 使用示例 |
---|---|---|
== | 相等 | [ $a == $b ] |
!= | 不等 | [ $a != $b ] |
整数间关系示例
a=15
b=20
# 相等
if [ ${a} -eq ${b} ]
then
echo "a==b"
fi
# 不等【true】
if [ ${a} -ne ${b} ]
then
echo "a!=b"
fi
# 大于
if [ ${a} -gt ${b} ]
then
echo "a>b"
fi
# 小于【true】
if [ ${a} -lt ${b} ]
then
echo "a<b"
fi
# 大于等于
if [ ${a} -ge ${b} ]
then
echo "a>=b"
fi
# 小于等于【true】
if [ ${a} -le ${b} ]
then
echo "a<=b"
fi
不同类型判等示例
a=(5 6)
b="5 6"
# 语法错误1 —— [: 参数太多
if [ ${a} != ${b} ]
then
echo "yes"
fi
# 无语法错误【"5" != "5 6":true】
if [ "${a}" != "${b}" ]
then
echo "yes"
fi
# 语法错误2 —— [: 参数太多
if [ "${a[@]}" != "${b}" ]
then
echo "yes"
fi
# 无语法错误【"5 6" != "5 6":false】
if [ "${a[*]}" != "${b}" ]
then
echo "yes"
fi
##################################
c=56
d="56a"
# 【"56" != "56a":true】
if [ "${c}" != "${d}" ]
then
echo "yes"
fi
Tips:
\qquad
建议在使用==
、!=
跨类别判等时,为使用的变量加上双引号"
、使用整个数组时用双引号"
和*
\qquad
有时候==
和[[ ]]
的一些特殊用法结合起来用时,可能会出现问题,要注意点
\qquad
比如[[ ${c}+${d} == 49 ]]
和[[ ${c}+${d}==49 ]]
的返回情况居然不一样,逻辑上判断应该是后者正确,也没搞明白为什么会这样(可能是运算符的优先级变了?)
3、逻辑运算符
逻辑运算,也就是与、或、非
逻辑非的写法只有一种,那就是[ ! 条件语句 ]
逻辑与的写法有两种
\qquad
一种是[ 条件语句1 -a 条件语句2 ]
\qquad
一种是[[ 条件语句1 && 条件语句2 ]]
逻辑或的写法有两种
\qquad
一种是[ 条件语句1 -o 条件语句2 ]
\qquad
一种是[[ 条件语句1 || 条件语句2 ]]
运算符 | 说明 | 使用示例 |
---|---|---|
! | 逻辑非 | [ ! $a -ge 0 ] |
-a | 逻辑与 | [ $a -ge 0 -a $b -ge 0 ] |
-o | 逻辑或 | [ $a -ge 0 -o $b -ge 0 ] |
&& | 逻辑与 | [[ $a -ge 0 && $b -ge 0 ]] |
|| | 逻辑或 | [[ $a -ge 0 || $b -ge 0 ]] |
使用示例
c=4
d=45
# 【true】
if [ ${c} == 4 -a ${d} == 45 ]
then
echo "yes1"
fi
# 【true】
if [[ ${c} == 4 && ${d} == 45 ]]
then
echo "yes2"
fi
# 【false】
if [ ${c} != 4 -o ${d} != 45 ]
then
echo "yes3"
fi
# 【false】
if [[ ${c} != 4 || ${d} != 45 ]]
then
echo "yes4"
fi
# 【true】
if [[ ! ${c} != 4 ]]
then
echo "yes5"
fi
[[ ]]
的条件表达式与[ ]
的条件表达式不同(关于这一点,可见博客 shell逻辑判断&&和-a区别)
\qquad
[[ ]]
中可以使用>
、<
直接判断大于小于,也可以使用-gt
、-le
等运算符
\qquad
[ ]
中只能使用-gt
、-le
等运算符,>
、<
会被误解成重定向符号
\qquad
[[ ]]
中只能使用&&
、||
进行逻辑与、逻辑或
\qquad
[ ]
中只能使用-a
、-o
进行逻辑与、逻辑或
\qquad
[[ ]]
中可以直接使用+
、-
等算术运算符(进行了算术扩展)
\qquad
[ ]
中不能直接使用+
、-
等算术运算符
\qquad
[[ ]]
中可以直接使用正则表达式
\qquad
[ ]
中无法直接使用正则表达式
使用示例
c=4
d=45
# 可以直接使用<,必须使用&&【true】
if [[ ${c} < ${d} && ${d} -gt ${c} ]]
then
echo "yes1"
fi
# 可以直接使用+【true】
if [[ ${c}+${d} -eq "49" ]]
then
echo "yes2"
fi
# 可以直接使用正则表达式(不要加上引号)【true】
if [[ ${d} == *5 ]]
then
echo "yes3"
fi
4、字符串运算符
字符串相关运算符如下表所示:
运算符 | 说明 | 使用示例 |
---|---|---|
= | 相等 | [ $a = $b ] |
!= | 不等 | [ $a != $b ] |
-z | 长度为0 | [ -z "$a" ] |
-n | 长度非0 | [ -n "$a" ] |
非空 | [ $a ] |
使用示例
a=" "
b="123a"
c="123a"
# 【true】
if [ "${b}" = "${c}" ]
then
echo "yes1"
fi
# 【true】
if [ "${a}" != "${c}" ]
then
echo "yes2"
fi
# 【false】
if [ -z "${a}" ]
then
echo "yes3"
fi
# 【true】
if [ -n "${a}" ]
then
echo "yes4"
fi
# 【true】
if [ "${a}" ]
then
echo "yes5"
fi
Tips:
\qquad
多加引号,比如${a}
有时候最好写成"${a}"
,否则空格串很有可能被处理成空串
5、文档测试运算符
文件测试运算符用于检测Linux的文件的各种属性
运算符(大致使用格式) | 说明 |
---|---|
-b file | 检测file 是否是块设备文件 |
-c file | 检测file 是否是字符设备文件 |
-d file | 检测file 是否是目录 |
-f file | 检测file 是否是普通文件 |
-S file | 检测file 是否为Socket |
-L file | 检测file 是否为符号链接 |
-g file | 检测file 是否设置了SGID位 |
-k file | 检测file 是否设置了粘着位(Sticky Bit) |
-u file | 检测file 是否设置了SUID位 |
-p file | 检测file 是否有名管道 |
-r file | 检测file 是否可读 |
-w file | 检测file 是否可写 |
-x file | 检测file 是否可执行 |
-s file | 检测file 是否非空 |
-e file | 检测file 是否存在 |
使用示例
# 【全部为true】
if [ -f test.sh ]
then
echo "文件存在"
fi
if [ -s test.sh ]
then
echo "文件非空"
fi
if [ -w test.sh ]
then
echo "文件可写"
fi
if [ -x test.sh ]
then
echo "文件可执行"
fi
6、test
命令
test
命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
由于和上面许多运算符类似,也将其放到运算符下了
test 条件语句
可以相当于[ 条件语句 ]
,也就是test
命令不需要加上[ ]
(1).数值测试
运算符 | 说明 | 使用示例 |
---|---|---|
-eq | 相等 | test $a -eq $b |
-ne | 不等 | test $a -ne $b |
-gt | 大于 | test $a -gt $b |
-lt | 小于 | test $a -lt $b |
-ge | 大于等于 | test $a -ge $b |
-le | 小于等于 | test $a -le $b |
使用示例
a=15
b=20
# 相等
if test ${a} -eq ${b}
then
echo "a==b"
fi
# 不等【true】
if test ${a} -ne ${b}
then
echo "a!=b"
fi
(2).字符串测试
运算符 | 说明 | 使用示例 |
---|---|---|
= | 相等 | test $a = $b |
!= | 不等 | test $a != $b |
-z | 长度为0 | test -z "$a" |
-n | 长度非0 | test -n "$a" |
非空 | test $a |
使用示例
a=" "
b="123a"
c="123a"
# 【true】
if test "${b}" = "${c}"
then
echo "yes1"
fi
# 【true】
if test "${a}" != "${c}"
then
echo "yes2"
fi
# 【false】
if test -z "${a}"
then
echo "yes3"
fi
# 【true】
if test -n "${a}"
then
echo "yes4"
fi
# 【true】
if test "${a}"
then
echo "yes5"
fi
(3).文件测试
运算符(大致使用格式) | 说明 |
---|---|
-b file | 检测file 是否是块设备文件 |
-c file | 检测file 是否是字符设备文件 |
-d file | 检测file 是否是目录 |
-f file | 检测file 是否是普通文件 |
-S file | 检测file 是否为Socket |
-L file | 检测file 是否为符号链接 |
-g file | 检测file 是否设置了SGID位 |
-k file | 检测file 是否设置了粘着位(Sticky Bit) |
-u file | 检测file 是否设置了SUID位 |
-p file | 检测file 是否有名管道 |
-r file | 检测file 是否可读 |
-w file | 检测file 是否可写 |
-x file | 检测file 是否可执行 |
-s file | 检测file 是否非空 |
-e file | 检测file 是否存在 |
使用示例
# 【全部为true】
if test -w test.sh
then
echo "文件可写"
fi
if test -x test.sh
then
echo "文件可执行"
fi
(4).组合逻辑运算符
Shell 还提供了与-a
、或-o
、非!
三个逻辑操作符用于将测试条件连接起来
其优先级为: !
> -a
> -o
使用示例
# 【true】
if test ! -S test.sh -a -w test.sh
then
echo "yes1"
fi
八、流程控制语句
1、条件判断语句
(1).if
语句
一般格式如下:
if 条件表达式
then
命令1
命令2
elif 条件表达式2
then
命令3
命令4
else
命令5
命令6
fi
简单示例
a=1
b=2
c=3
# 【true】
if [ $((--a)) == 0 ]
then
echo "yes"
fi
# 【false】
if [ ${b} -ge ${c} ]
then
echo "b >= c"
# 【true】
elif [ $((a--)) == 0 ]
then
echo "b < c && a-- == 0"
# 【false】
else
echo "b < c && a-- != 0"
fi
echo ${a} # -1
(2).case
语句
一般格式如下:
case 值 in
模式1)
命令1
命令2
;;
模式2)
命令3
命令4
;;
*)
命令5
命令6
;;
esac
注:
\qquad
① 双分号;;
作为每个分支的结束,而不是break
\qquad
② 在模式匹配中,不加双引号可以使用*
、?
等通配符
Tips:有关通配符的介绍,推荐下面几篇博文
\qquad
Linux之通配符
\qquad
Linux通配符和正则表达式
简单示例
a=123
b=123
c=123
d=124
# 输出:匹配"123"
case ${a} in
1)
echo "匹配\"1\""
;;
123)
echo "匹配\"123\""
;;
*)
echo "匹配default——*"
;;
esac
# 输出:匹配*3
case ${b} in
1)
echo "匹配\"1\""
;;
*3)
echo "匹配\"*3\""
;;
*)
echo "匹配default——*"
;;
esac
# 输出:匹配default——*
case ${c} in
1)
echo "匹配\"1\""
;;
"*3")
echo "匹配\"*3\""
;;
*)
echo "匹配default——*"
;;
esac
# 输出:匹配default——*
case ${d} in
1)
echo "匹配\"1\""
;;
*3)
echo "匹配\"*3\""
;;
*)
echo "匹配default——*"
;;
esac
2、循环语句
(1).for
循环
一般格式如下:
for 变量 in 可迭代对象
do
命令1
命令2
done
无限循环
for (( ; ; ))
do
命令
done
简单示例
for var in 1 2 3 4 5
do
echo ${var}
done
# 输出:1(换行)2(换行)3(换行)4(换行)5(换行)
for filename in `ls`
do
echo ${filename}
done
# 输出:test.sh(换行)
(2).while
循环
一般格式如下:
while 条件表达式
do
命令
done
可以把read
命令放入while
语句的条件表达式,循环读取键盘输入(直到输入Ctrl + D
)
while read 变量
do
命令
done
无限循环格式
# 格式1
while true
do
命令
done
# 格式2
while :
do
命令
done
简单示例
a=1
while [ ${a} -lt 10 ]
do
let a+=3
echo ${a}
done
# 【输出】
# 4
# 7
# 10
while read -p "请输入你的名字(输入Ctrl+D结束):" abc
do
echo "你的名字是${abc}"
done
# 【使用案例】
# 请输入你的名字(输入Ctrl+D结束):excious
# 你的名字是excious
# 请输入你的名字(输入Ctrl+D结束):dinggou
# 你的名字是dinggou
# 请输入你的名字(输入Ctrl+D结束):
(3).until
循环
一般格式如下:
until 条件表达式
do
命令
done
本质上和while
是等效的(并不像其他语言的do while
循环),一般while
循环优于until
循环
简单示例
a=-1
until [ ${a} == 0 ]
do
echo $((++a))
done
# 【输出】
# 0
(4).跳出循环
break
跳出整个循环,退出循环体
continue
跳出某次循环,继续下一次循环
简单示例
a=10
while [ ${a} -ge 0 ]
do
let a--
# 判断偶数
if [ $((a%2)) == 0 ]
then
break
fi
echo ${a}
done
echo "-------"
b=10
while [ ${b} -ge 0 ]
do
let b--
# 判断偶数
if [ $((b%2)) == 0 ]
then
continue
fi
echo ${b}
done
# 【输出】
# 9
# -------
# 9
# 7
# 5
# 3
# 1
# -1
九、函数
函数的格式如下:
# 函数定义
[ function ] 函数名 [ () ]
{
函数体
[ return 0-255间的整数值 ]
}
# 函数调用
函数名 [ 参数列表 ]
注:
\qquad
① 不写return
语句,将把函数体内最后一条命令的返回值作为函数的返回值
\qquad
② 调用函数后,通过$?
获取函数的返回值
\qquad
③ 向函数传参的格式与 向shell脚本传参 的格式相同,函数体内$*
等获得的是传入函数的参数而非传入shell脚本的参数
简单示例
mytest()
{
cnt=0
for arg in $*
do
echo ${arg}
let cnt++
done
return ${cnt}
}
mytest 12 34 545
echo $?
# 使用示例:
# ./test.sh 565 68 53
# 12
# 34
# 545
# 3
十、输入/输出重定向
输入/输出重定向的指令如下:
命令 | 说明 |
---|---|
命令 > file | 将命令的输出重定向到file 文件中(创建/覆盖) |
命令 >> file | 将命令的输出重定向到file 文件中(创建/追加) |
命令 < file | 将命令的输入重定向到file 文件中 |
<< tag | 将开始标记tag 和结束标记tag 之间的内容作为输入(这种称为shell中的Here Document) |
一般情况下,每个 Linux 命令运行时都会打开三个文件:
- 标准输入文件(
stdin
):stdin的文件描述符为0,默认从stdin
读取数据 - 标准输出文件(
stdout
):stdout 的文件描述符为1,默认向stdout
输出数据 - 标准错误文件(
stderr
):stderr的文件描述符为2,向stderr
流中写入错误信息
默认情况下,命令 > file
将 stdout
重定向到 file
,命令 < file
将 stdin
重定向到 file
简单示例
# 命令的结果重定向到文件
who > test.txt
# 从文件输入参数到命令
wc -l < test.txt
# 同时为输入和输出进行重定向
wc -l < test.txt > test2.txt
# 长自定义输入
wc -l << tag
> tgis
> ewi
> ee
> 134
>
> 231
> tag
示例截图
\qquad
Tips:
\qquad
如果不希望命令的结果在屏幕上显示,可以将命令的输出结果重定向到/dev/null
这一文件
\qquad
/dev/null
是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到
十一、文件包含
在Shell中,可以使用文件包含,即在一个sh脚本中引用另一个sh脚本的内容
其格式如下
# 方式1
. 脚本位置
# 方式2
source 脚本位置
注:
\qquad
被引用的脚本文件并不需要拥有可执行权限
简单示例
test.sh
文件test1="yes, this is test1" echo "test.sh loaded"
test2.sh
文件. test.sh source test.sh echo ${test1}
示例截图
\qquad