《Linux编程》学习笔记 ·003【Shell编程】
注:前言、目录见 https://blog.csdn.net/qq_44220418/article/details/108428971
Tips:其实主要也就是把菜鸟教程上的shell编程教程过了一遍,自己探索了一部分,记录了自己的所得与理解
文章目录
- 一、注释
- 二、输出
- 1、`echo`命令
- 2、`printf`命令
- 三、变量
- 1、定义
- 2、使用
- 3、删除
- 四、字符串
- 1、表示
- 2、拼接
- 3、长度
- 4、截子串
- 5、查位置
- 五、数组
- 1、定义
- 2、取元素
- 3、长度
- 六、运行与传参
- 1、运行
- 2、运行传参
- 七、运算符
- 1、算术运算符
- 2、关系运算符
- (1).条件表达式
- (2).关系运算符
- 3、逻辑运算符
- 4、字符串运算符
- 5、文档测试运算符
- 6、`test`命令
- (1).数值测试
- (2).字符串测试
- (3).文件测试
- (4).组合逻辑运算符
- 八、流程控制语句
- 1、条件判断语句
- (1).`if`语句
- (2).`case`语句
- 2、循环语句
- (1).`for`循环
- (2).`while`循环
- (3).`until`循环
- (4).跳出循环
- 九、函数
- 十、输入/输出重定向
- 十一、文件包含
一、注释
#单行注释:<<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∼70 \sim 70∼7的数字(或者缺省)
|
'\65' 就相当于ASCII编码为53 的字符'5'
|
\0ddd
|
d 代表一个0∼70 \sim 70∼7的数字(或者缺省)
|
'\0065' 就相当于ASCII编码为53 的字符'5'
|
\xddd
|
d 代表一个0∼f0 \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=2b=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" # 1234112421414a=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]} # 3echo ${#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=5echo `expr ${a} + ${b}` # 26
echo `expr ${a} - ${b}` # 16
echo `expr ${a} \* ${b}` # 105
echo `expr ${a} / ${b}` # 4
echo `expr ${a} % ${b}` # 1echo $((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
条件语句是条件表达式的一部分,可以说,给条件语句加上适当的格式就成了条件表达式
eg: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} ]
thenecho "a==b"
fi# 不等【true】
if [ ${a} -ne ${b} ]
thenecho "a!=b"
fi# 大于
if [ ${a} -gt ${b} ]
thenecho "a>b"
fi# 小于【true】
if [ ${a} -lt ${b} ]
thenecho "a<b"
fi# 大于等于
if [ ${a} -ge ${b} ]
thenecho "a>=b"
fi# 小于等于【true】
if [ ${a} -le ${b} ]
thenecho "a<=b"
fi
不同类型判等示例
a=(5 6)
b="5 6"# 语法错误1 —— [: 参数太多
if [ ${a} != ${b} ]
thenecho "yes"
fi# 无语法错误【"5" != "5 6":true】
if [ "${a}" != "${b}" ]
thenecho "yes"
fi# 语法错误2 —— [: 参数太多
if [ "${a[@]}" != "${b}" ]
thenecho "yes"
fi# 无语法错误【"5 6" != "5 6":false】
if [ "${a[*]}" != "${b}" ]
thenecho "yes"
fi##################################c=56
d="56a"# 【"56" != "56a":true】
if [ "${c}" != "${d}" ]
thenecho "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 ]
thenecho "yes1"
fi# 【true】
if [[ ${c} == 4 && ${d} == 45 ]]
thenecho "yes2"
fi# 【false】
if [ ${c} != 4 -o ${d} != 45 ]
thenecho "yes3"
fi# 【false】
if [[ ${c} != 4 || ${d} != 45 ]]
thenecho "yes4"
fi# 【true】
if [[ ! ${c} != 4 ]]
thenecho "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} ]]
thenecho "yes1"
fi# 可以直接使用+【true】
if [[ ${c}+${d} -eq "49" ]]
thenecho "yes2"
fi# 可以直接使用正则表达式(不要加上引号)【true】
if [[ ${d} == *5 ]]
thenecho "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}" ]
thenecho "yes1"
fi# 【true】
if [ "${a}" != "${c}" ]
thenecho "yes2"
fi# 【false】
if [ -z "${a}" ]
thenecho "yes3"
fi# 【true】
if [ -n "${a}" ]
thenecho "yes4"
fi# 【true】
if [ "${a}" ]
thenecho "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 ]
thenecho "文件存在"
fiif [ -s test.sh ]
thenecho "文件非空"
fiif [ -w test.sh ]
thenecho "文件可写"
fiif [ -x test.sh ]
thenecho "文件可执行"
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}
thenecho "a==b"
fi# 不等【true】
if test ${a} -ne ${b}
thenecho "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}"
thenecho "yes1"
fi# 【true】
if test "${a}" != "${c}"
thenecho "yes2"
fi# 【false】
if test -z "${a}"
thenecho "yes3"
fi# 【true】
if test -n "${a}"
thenecho "yes4"
fi# 【true】
if test "${a}"
thenecho "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
thenecho "文件可写"
fiif test -x test.sh
thenecho "文件可执行"
fi
(4).组合逻辑运算符
Shell 还提供了与-a
、或-o
、非!
三个逻辑操作符用于将测试条件连接起来
其优先级为: !
> -a
> -o
使用示例
# 【true】
if test ! -S test.sh -a -w test.sh
thenecho "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 ]
thenecho "yes"
fi# 【false】
if [ ${b} -ge ${c} ]
thenecho "b >= c"
# 【true】
elif [ $((a--)) == 0 ]
thenecho "b < c && a-- == 0"
# 【false】
elseecho "b < c && a-- != 0"
fiecho ${a} # -1
(2).case
语句
一般格式如下:
case 值 in
模式1)命令1命令2;;
模式2)命令3命令4;;
*)命令5命令6;;
esac
注:
\qquad① 双分号;;
作为每个分支的结束,而不是break
\qquad② 在模式匹配中,不加双引号可以使用*
、?
等通配符
Tips:有关通配符的介绍,推荐下面几篇博文
\qquadLinux之通配符
\qquadLinux通配符和正则表达式
简单示例
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
doecho ${var}
done
# 输出:1(换行)2(换行)3(换行)4(换行)5(换行)for filename in `ls`
doecho ${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=1while [ ${a} -lt 10 ]
dolet a+=3echo ${a}
done# 【输出】
# 4
# 7
# 10while read -p "请输入你的名字(输入Ctrl+D结束):" abc
doecho "你的名字是${abc}"
done# 【使用案例】
# 请输入你的名字(输入Ctrl+D结束):excious
# 你的名字是excious
# 请输入你的名字(输入Ctrl+D结束):dinggou
# 你的名字是dinggou
# 请输入你的名字(输入Ctrl+D结束):
(3).until
循环
一般格式如下:
until 条件表达式
do命令
done
本质上和while
是等效的(并不像其他语言的do while
循环),一般while
循环优于until
循环
简单示例
a=-1until [ ${a} == 0 ]
doecho $((++a))
done# 【输出】
# 0
(4).跳出循环
break
跳出整个循环,退出循环体
continue
跳出某次循环,继续下一次循环
简单示例
a=10
while [ ${a} -ge 0 ]
dolet a--# 判断偶数if [ $((a%2)) == 0 ]thenbreakfiecho ${a}
doneecho "-------"b=10
while [ ${b} -ge 0 ]
dolet b--# 判断偶数if [ $((b%2)) == 0 ]thencontinuefiecho ${b}
done# 【输出】
# 9
# -------
# 9
# 7
# 5
# 3
# 1
# -1
九、函数
函数的格式如下:
# 函数定义
[ function ] 函数名 [ () ]
{函数体[ return 0-255间的整数值 ]
}# 函数调用
函数名 [ 参数列表 ]
注:
\qquad① 不写return
语句,将把函数体内最后一条命令的返回值作为函数的返回值
\qquad② 调用函数后,通过$?
获取函数的返回值
\qquad③ 向函数传参的格式与 向shell脚本传参 的格式相同,函数体内$*
等获得的是传入函数的参数而非传入shell脚本的参数
简单示例
mytest()
{cnt=0for arg in $*doecho ${arg}let cnt++donereturn ${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.shsource test.shecho ${test1}
示例截图
\qquad
《Linux编程》学习笔记 ·003【Shell编程】相关推荐
- 嵌入式Linux基础学习笔记-文件IO编程-I/O多路复用
实验内容:多路复用-I/O操作及阻塞 编程实现文件描述符集合的监听 multiplex_poll.c文件编写: /* multiplex_poll.c */ #include <fcntl.h& ...
- 嵌入式Linux基础学习笔记-文件IO编程-文件锁(2)
文件操作仿真FIFO,实现生产者-消费者运行模型 编程实现生产者程序producer.c,创建仿真FIFO结构文件(普通文件),按照给定的时间间隔向FIFO文件写入自动生成的字符(自定义),生产周期及 ...
- 嵌入式Linux基础学习笔记-文件IO编程-文件锁(1)
文件锁-文件共享 共享资源竞争问题的解决方法:文件锁. 文件锁包括 建议性锁 要求每个上锁文件的进程都要检查是否有锁存在,并且尊重 已有的锁 强制性锁 由内核执行的锁,当一个文件被上锁进行写入操作的时 ...
- TCP/IP网络编程 学习笔记_1 --网络编程入门
前言:这个系列网络编程教程实例代码是在Xcode上运行的,MacOSX,是一个基于UNIX核心的系统,所以基于Linux的网络编程代码一般可以直接在Xcode上运行,如果要移植到Windows其实就只 ...
- python编程学习笔记列表_python编程:从入门到实践学习笔记-函数
Python学习资料或者需要代码.视频加Python学习群:516107834 定义函数 举个简单的例子 由上所示,关键字def定义一个函数,后面跟着函数名以及用来输入参数的括号,定义以冒号结束,而p ...
- shell脚本编程学习笔记1(xdl)——shell基础与Bash基本功能()
shell脚本编程学习笔记1--shell基础与Bash基本功能 1,简介: 1,Shell就是一个命令行解释器,用以连接输入设别和内核. 2,Shell是解 释执行的脚本语言,在Shell中可以直接 ...
- 《Linux Shell编程学习笔记之一》
<Linux Shell编程学习笔记之一> 前言 由于自己一直在Windows上面编程,用linux用的比较少,学习linux还是本科大二学的一点点知识.因此自己就准备花点时间来熟悉下li ...
- Linux Shell编程学习笔记(4)
Linux Shell编程学习笔记(2015-7-20) 分类:linux shell 今天学习了Linux Shell中的控制结构.其实大多数语言的控制结构这一块都是基本类似的,有了C语言的基础 ...
- Linux Shell编程学习笔记(2)
Linux Shell编程学习笔记(2015-7-12) 分类:linux shell Shell变量 一:关于Shell变量 Shell是一种弱类型的语言,变量存储的一切值都是字符串.Shell ...
- Linux Shell编程学习笔记(3)
Linux Shell编程学习笔记(2015-7-19) 分类:linux shell 一:位置参数和特殊变量 什么是位置参数? 位置参数也叫位置变量,是运行shell脚本程序时,命令行she ...
最新文章
- 从0到1,从概念到国际标准,蚂蚁共享智能凭什么?
- outlook搜索不到历史邮件内容
- P3731 二分图匹配必经边
- 概念验证:玩! 构架
- LeetCode 2201. 统计可以提取的工件(哈希)
- [转载]保护 ASP.NET 应用程序的安全
- 用开源代码如何建立网站_在开源上建立自举业务
- d3 v5 api select
- 【poj3375】 Network Connection
- [导入]给老家新楼的对联
- Cannot resolve table 't_daily'
- TensorFlow精进之路(一):Softmax回归模型训练MNIST
- Unidac连接出错:命名管道提供程序:管道的另一端上无任何进程.
- LapStyle - 基于拉普拉斯金字塔的高质量风格化方法 | CVPR2021
- Robo 3T 使用教程
- Win7强制删除文件或文件夹
- mac下配置subl启动sublime text 编辑器
- PTGUI全景合成软件使用教程之控制点设置
- 嵌入式属于人工智能吗?
- 解决时间插件mobiscroll在使用过程中的一个小缺陷
热门文章
- mac java连通r_MacOS安装rJava
- mongodb空间查询java,java查看mongodb集合表空间大小
- 台达ms300变频器使用手册中文_台达变频器:满足未来驱动需求
- python定时器 是线程吗_定时器中断线程python
- 哈工大理论力学第八版电子版_理论力学哈工大第八版1第一章思考题课后题
- Python之对list进行切片
- 洛谷 | P1010 幂次方
- NumPy————NumPy广播机制的学习笔记
- PostgreSQL and SQLAlchemy [ubuntu]
- stm32的串口DMA空闲中断接收不等长数据,stm32F1的usart1-DMA-IDLE收发