什么是shell
1. Shell 是一个用C语言编写的应用程序,它是用户使用Linux的桥梁。
2. Shell既是一种命令语言,又是一种程序设计语言。
3. Shell是值一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
脚本和环境
Shell脚本, 它是一种为shell编写的脚本程序。
Shell环境,使用一个能编写代码的文本编辑器 vi 和一个能解释执行的脚本解释器。如:/bin/bash。
Linux的Shell种类众多,常见的有:
1. /usr/bin/sh 或 /bin/sh
2. /bin/bash (常用、默认)
3. /usr/bin/csh
...
作用
在Shell中,将许多命令写在一起,让用户很轻松的就能执行一个文件的Shell脚本,就能够一次执行多个命令。
基本格式
- 创建文件:vi 脚本名字.sh
脚本第一行格式:
#!/bin/bash
符号#!用来指定该脚本文件的解析程序,这里使用的是bin目录下的bash解析器。
第一个脚本:vi hello.sh
#!/bin/bash echo 'hello word'
脚本执行:
1. /bin/bash 脚本名 (推荐)
2. chmod +x 脚本名 -> ./脚本名
注意事项:
- chmod + x file 加上执行权限,否则会提示无执行权限。
- 脚本后缀名可以任意修改,仍然可以正常运行。
Shell中的变量
变量:在程序运行过程中可以改变的量。
变量命名规则:
- 首个字符必须为字符(a-z,A-Z)。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
- 不能使用bash里的关键字。
变量声明格式 : 变量名 = 变量值
注:变量名和=之间不能有空格。
#!/bin/bash you_name="qt" echo $you_name # 变量名前需要加$,或者 ${you_name},加花括号是为了帮助解释器识别变量的边界。
注意:在echo 字符串时,如果里面存在变量时,这个字符串要用""包裹,而不能使用'',
echo 'this is $you_name' # this is $you_name
echo "this is $you_name" # this is qt
只读变量
使用 readonly 命令可以将变量定义为只读变量。
#!/bin/bash readonly you_name="qt" echo $you_name # 输出qt you_name='tt' echo $you_name # 报错,并输出 qt
删除变量
使用 unset 命令可以删除变量
#!/bin/bash you_name="qt" echo $you_name # qt unset you_name echo $you_name # 空 # 注:当变量是 readonly 时,使用 unset 会报错
字符串操作
- 拼接字符串
-
#!/bin/bash name="hello" res="$name word" echo $res
-
- 获取字符串长度:${#变量名}
-
#!/bin/bash name="hello" res="$name word" echo ${#res}
-
- 提取子字符串:${变量名:截取字符的下标:截取的长度}
-
#!/bin/bash name="hello" res="$name word" echo ${res:1:4}
-
数组
定义:用括号代表数组,数组元素用“空格”符号分隔开。
形式:数组名=(值1 值2 ... 值n)
#!/bin/bash num=(44 11 'hello' 'word') # 定义数组并赋值,由此可见,数组中可以存放不同类型的数据 echo ${num[0]} # 获取数组中下标为0的值 echo ${num[2]} # 获取数组中下标为2的值
- 获取数组中所有的元素:${数组名[@]}
-
#!/bin/bash num=(44 11 'hello' 'word') echo ${num[@]} # 获取所有元素 echo ${num} # 当不带下标时,默认输入第一个元素,44
-
- 获取数组的长度:${#数组名[@]}
-
#!/bin/bash num=(44 11 'hello' 'word') echo ${#num[@]} # 4
-
- 获取数组中单个元素的长度:${#数组名[下标]}
-
#!/bin/bash num=(44 11 'hello' 'word') echo ${#num[1]} # 2
-
数组练习:(直接复制运行即可,用于了解以上知识点)
#/bin/bash a=(1 2 3 "word" 12.32) echo "数组中的所有元素:${a[@]}" echo "获取数组中的长度:${#a[@]}" echo "获取数组中单个元素的长度:${#a[3]}"
注释
以“#”开头的行就是注释,会被解释器忽略。第一行的#是解释说明,并不是注释!
sh里没有多行注释,只能每行接一个#。
基本运算符
> 算术运算符
> 关系运算符
> 布尔运算符
> 逻辑运算符
> 字符串运算符
> 文件测试运算符
第一种运算方式:expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
两个数相加(注意使用的是反引号` 而不是单引号 ')。
#!/bin/bash exp=`expr 2 + 2` # 表达式之间需要用空格 echo "sum: $exp"
第二种运算方式:$(()) 【推荐】
#!/bin/bash a=20 b=10 c=$(($a * $b)) echo $c 优点:不需要考虑空格的问题,*运算时不需要进行转义
- 算术运算符
- + `expr $a + $b` 加
- - `expr $a - $b` 减
- * `expr $a * $b` 乘(使用这个字符时需要对它进行转义)
- / `expr $a / $b` 除
- % `expr $a % $b` 取余
- = `expr $a = $b` 等于
-
#/bin/bash a=10 b=20 echo "加:`expr $a + $b`" echo "减:`expr $a - $b`" echo "乘:`expr $a * $b`" echo "除:`expr $a / $b`" echo "取余:`expr $a % $b`" echo "相等:`expr $a = $b`" echo "恒等:`expr $a == %b`"
# 算术运算符练习:(直接复制运行即可,了解以上知识点)
- 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
假定变量 a =10, b=20;
- -eq 检测两个数是否相等,相等返回true
- -ne 检测两个数是否相等,不相等返回true
- -gt 检测左边的数是否大于右边
- -lt 检测左边的数是否小于右边
- -ge 检测左边的数是否大于等于右边
- -le 检测左边的数是否小于等于右边
-
#!/bin/bash read a if [ $a -lt 10 ] then echo "10 大于 $a" fi if [ $a -gt 10 ] then echo "10 小于 $a" fi if [ $a -eq 10 ] then echo "$a 等于 10" fi if [ $a -ne 10 ] then
3. 布尔运算符
- ! 非运算
-
#!/bin/bash c=false if [ !$c ] then echo '相等' else echo '不相等' fi
# 输出:相等
-
- -o 或运算
-
#!/bin/bash a=10 b=20 if [ $a -gt 5 -o $b -lt 10 ] then echo 'true' else echo 'false' fi
# 输出:true
-
- -a 与运算
-
#!/bin/bash a=10 b=20 if [ $a -gt 5 -a $b -lt 10 ] then echo 'true' else echo 'false' fi
# 输出:false
-
4. 逻辑运算符
- && 逻辑与 如:[[$a -lt 100 && $b -gt 100]]
- || 逻辑或 如:[[$a -lt 100 || $b -gt 100]]
5. 字符串运算符
假定 a='abc' b='dfg'
- = 检测两个字符串是否相等
- != 检测两个字符串是否相等,不相等返回true。
- -z 检测字符串长度是否为0,为0 返回true
- -n 检测字符串长度是否为0,不为0返回true
- str 检测字符串是否为空(null),不为空返回true,如:[$a]返回true
6. 文件测试运算符
文件测试运算符用于检测文件的各种属性。file可赋值为路径。如:file=/root/test.sh
- -d file 检测文件是否是目录,如果是,则返回true。如:[ -d $file ] 返回true。
- -f file 检测是否是普通文件。如:[ -f $file ] 返回true。
- -r file 检测是否可读。如:[ -r $file ] 返回ture。
- -w file 检测是否可写。
- -x file 检测是否可执行。
- -s file 检测文件是否为空(文件大小是否大于0)
- -e file 检测文件(目录)是否存在。
关于echo命令
作用:用于字符串的输出。格式: echo "字符串内容"
- 显示转义字符 echo ""It is a test""
- 显示变量
- read 命令 从标准输入中读取一行,并把输入行的每个字段赋值给变量。
- 格式: read 变量名
-
#!/bin/bash
echo -e "请输入str变量的值:c"
read str
echo "您输入的变量值为:$str"# 输入:hello word
# 输出:hello word
- 显示换行
- -e 开启转义
- 显示不换行
-
#!/bin/bash echo -e "it is good c" echo "testing" # 输出:it is good testing
-
- 显示结果定向至文件
-
#!/bin/bash
echo "it is beautiful" > file # 将echo的结果定向保存到file文件中
# 如果file中有文本,则覆盖里面的内容
# 追加是:>>
-
- 显示命令执行结果
-
#!/bin/bash echo `date` # 输出:Sun Apr 5 11:52:27 CST 2022
# 即:反引号`包裹的内容,会将他们作为命令执行。
-
练习:从终端中读取两个数据,判断其大小。
#!/bin/bash echo -e "请输入第一个数字:c" read n1 echo -e "请输入第二个数字:c" read n2 if [ $n1 -eq $n2 ] then echo "两数相等" fi if [ $n1 -lt $n2 ] then echo "$n2 比 $n1 大" fi if [ $n1 -gt $n2 ] then echo "$n1 比 $n2 大" fi
常见的转义字符
注:在shell脚本中,除了转义符号之外,其他的转义操作都必须要借助于参数开启转义 -e
- 后退(删除前一个字符)
- 换行(回车)
- 水平制表符
- 清除前面的字符
- c 不换行
- \
- "
echo "hello word" # 输出:hello word echo -e "hello word" # -e 开启转义 # 输出: # hello # word
关于printf命令
格式:printf 格式声明 与格式声明相对应的参数列表
格式声明由两部分组成:百分比符号(%)和指示符。
- %d:data 数字 -- 对应位置参数必须是数字型
- %s:str 字符串 -- 对应位置参数必须是字符串
- %c:char 字符 -- 对应位置是显示相对应参数的第一个字符
- %f:float 浮点 -- 对应位置参数必须是浮点型
#!/bin/bash printf "%-10s %-3.2f %-3c %2d " name 0.12 aaa 20 # 注: # %-10s:指一个宽度为10个字符(- 表示左对齐,没有则表示右对齐) # 任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来 # %-3.2f:指格式化为小数,总共3位,其中 .2 表示保留两位小数
----------------
printf "%s %s %s " a b c d e f g h i
# 输出:当传递内容过多时,会根据格式进行自动划分分组显示。
# a b c
# d e f
# g h i
关于test命令
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
- -eq (相等)
- -ne (不等)
- -gt (大于)
- -ge (大于等于)
- -lt (小于)
- -le (小于等于)
数值举例:字符和文件测试相同,参考前面的字符、文件运算符。
#!/bin/bash echo -e "请输入第一个数字:c" read a echo -e "请输入第二个数字:c" read b if test $a -eq $b then echo "$a 和 $b 相等" else echo "两者不相等" fi
练习:给定一个数字,判断奇偶数。
#!/bin/bash echo -e "请输入第一个数字:c" read a if test `expr $a % 2` -eq 0 then echo "$a 是偶数" else echo "$a 是奇数" fi
优先级问题:
“!”最高,“-a”次之,“-o”最低。(布尔运算符)
if语句
格式:
#!/bin/bash if [条件] # 前面提到过:这里的[] 可以直接使用 test 进行条件判断 then 语句 elif [条件] then 语句 else 语句 fi
练习:参加考试,90-100:奖励证书;70-90:奖励红花;60-70:奖励一巴掌;0-60:请离家出走;<0:输入错误。
#!/bin/bash echo -e "请输入成绩:c" read a if test $a -ge 90 -a $a -le 100 then echo "奖励证书" elif test $a -ge 70 -a $a -lt 90 then echo "奖励小红花" elif test $a -ge 60 -a $a -lt 70 then echo "奖励一个大嘴巴子" elif test $a -ge 0 -a $a -lt 60 then echo "请离家出走" else echo "输入错误" fi
条件判断(case ... esac 语句)
格式:
#!/bin/bash case $变量 in 值1) ... ;; 值2) ... ;; *) ... ;; esac
循环(while ... do ... done)
格式
while ((判断条件)) do ... done
# break 、continue
举例:
#!/bin/bash read a while (( $a >= 1 )) do let "a--" # let 命令,用于执行一个或多个表达式,变量计算中不需要加上$来表示变量 echo "a的值为 $a" done
练习:判断 0-100之间的偶数
#!/bin/bash i=1 while (($i<=100)) do if [ $(($i%2)) == 0 ] then echo $i fi let "i++" done
循环(for .. do ..done)
格式:
# 第一种格式
#!/bin/bash for ((初始值;条件;运算语句)) do ... dome
--------------
# 第二种格式
for 变量名 in 值1 值2 值3 ...
do
...
done
举例:
#!/bin/bash for ((i=1;i<5;i++)) do echo $i done
练习:统计1-100之间的奇数和偶数的个数
#!/bin/bash j=0 # 奇数个数 o=0 # 偶数个数 for((i=1;i<=100;i++)) do if [ $(($i%2)) == 0 ] then let "o++" else let "j++" fi done echo "奇数个数为:$j" echo "偶数个数为:$o"
Shell函数的定义、执行与传参
格式1:
function 函数名 (){ ... }
# 执行:函数名
格式2:
函数名 () {
...
}
# 执行:函数名
注:
全局变量:在脚本内,函数体外声明的变量为全局变量
局部变量:在函数中声明的变量,需要用 local 关键词修饰
关于函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例:$1 表示第一个参数,$2便是第二个参数。当 n>=10时,需要使用${n}来获取参数。 $# 统计当前参数总数,$* 获取的全部参数
例:
#!/bin/bash function test() { echo "第一个参数为:$1" echo "第二个参数为:$2" echo "第十个参数为:${10}" } test 1 2 3 4 5 6 7 8 9 10 11
# 输出
# 第一个参数为:1
# 第二个参数为:2
# 第十个参数为:10
关于函数中的返回值
函数返回值在调用之后通过 $? 获得。
举例:
#!/bin/bash function test() { echo -e "请输入第一个数:c" read a echo -e "请输入第一个数:c" read b return $(($a+$b)) } test echo "两数之和为:$?"
递归函数
自己调用自己
#!/bin/bash function test() { echo "aa" # 例子不好,无限循环,仅作参考 test } test
....持续更新