Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。
Shell 在线工具
1、shell变量
1.1定义变量及其赋值
1 | 普通变量 |
$(...)
可以扩展成另一个命令的运行结果,该命令的所有输出都会作为返回值。
1 | a=$(ls -l); #是一个字符串 |
1.2 使用变量
1 | 方式1: |
注:Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出。
\转义字符;后面两个需要开启转义 -e ;\n换行;\c不换行
1 | echo -e "OK! \c" # -e 开启转义 \c 不换行 |
1.3 删除变量
1 | unset name |
1.4 变量类型
运行shell时,会同时存在三种变量:
1) 局部变量 局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
2) 环境变量 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
3) shell变量 shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
1.5 Bash let 计算工具
let 命令是 BASH 中用于计算的工具,用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量,如果表达式的值是非0,那么返回的状态值是0;否则,返回的状态值是1。如果表达式中包含了空格或其他特殊字符,则必须引起来。还提供了方幂“**”运算符。
类似命令: wc bc dc expr
语法格式
1 | let arg [arg ...] |
参数说明:
arg:要执行的表达式
实例:
自加操作:let no++
自减操作:let no–
简写形式 let no+=10,let no-=20,分别等同于 let no=no+10,let no=no-20。
以下实例计算 a 和 b 两个表达式,并输出结果:
1 | let a=5+4 |
1.6 特殊变量
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名 |
$n | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。 |
$# | 传递给脚本或函数的参数个数。 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。 |
$? | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID。 |
1.7 字符类
1 |
|
$@和$通常在bash处理命令行参数的时候使用。两者在没有$@和$ “”引起来的情况下表示含义意义都是数组,如果使用双引号引起来则:
$@表示的是参数的数组类型当有多个参数的时候,每个参数占用一个数组元素。*
$*表示的是参数的字符串类型当有多个参数的时候,所有参数拼成一个长字符串作为一个参数
1 | !/bin/bash |
2、Shell 字符串
1、单引号
1 | name='dongdong' |
单引号字符串的限制:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
2、双引号
1 | name="dongdong" |
双引号的优点:
- 双引号里可以有变量
- 双引号里可以出现转义字符
3、字符串操作
3.1 拼接字符串
1 | name="dongdong" |
3.2 获取字符串长度
1 | echo ${#name} |
3.3 提取子字符串
1 | {dong:1:4} #注意:第一个字符的索引值为 0。 |
3.4 查找子字符串
查找字符 i 或 o 的位置(哪个字母先出现就计算哪个)
1 | string="runoob is a great site" |
1 | {#string} # $string的长度 |
3.5 字符串过滤和提取
1、字符串转数组(String.split(“oprator”))
1 | ----------------------------------方式一tr((!只能针对单个分隔符)单字符推荐)------------------------------- |
2、数组转字符串
1 | 数组转字符串 |
2、多行提取有用行
1 | grep dong #查找有关dong的行 |
3、正则提取
1 | echo office365 | grep -P '\d+' -o |
xargs会将find结果作为grep的输入,防止find结果过多无法处理
-P参数表明要应用正则表达式
-o表示只输出匹配的字符串,这样我们就可以把正则匹配到的结果拿到了。
4、awk 直接提取一行中需要的字段,无需转数组
1 |
3、数组
3.1数组的声明与定义
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。
与大部分编程语言类似,数组元素的下标由0开始。
Shell 数组用括号来表示,元素用”空格”符号分割开,语法格式如下:
1 | 方式一 |
*^( ̄(oo) ̄)^:有一个字符串 94 278 2083 test.sh,怎么转成数组呢?直接外层套个()
3.2 数组的读取
${数组名[下标]}
1 | valuen=${arr[1]} |
3.3数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
1 | 取得数组元素的个数 |
4、基本运算符
Shell 和其他编程语言一样,支持多种运算符,包括:
- 算数运算符
- 关系运算符
- 布尔运算符
- 字符串运算符
- 文件测试运算符
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
1 | 两个数相加(注意使用的是反引号 ` 而不是单引号 '): |
两点注意:
- 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
- 完整的表达式要被
4.1 算术运算符
+ | 加法 | expr $a + $b 结果为 30。 |
---|---|---|
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
ex:
1 | val=`expr $a + $b` |
4.2布尔运算符
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
EX:
1 | if [ $a -lt 100 -a $b -gt 15 ] |
4.3 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
4.4逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
1 | if [[ $a -lt 100 && $b -gt 100 ]] |
4.5字符串运算符
下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n “$a” ] 返回 true。 |
$ | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
1 | if [ -z $a ] |
4.6文件测试运算符
用于检测 Unix 文件的各种属性。
属性检测描述如下:
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
其他检查符:
- -S: 判断某文件是否 socket。
- -L: 检测文件是否存在并且是一个符号链接。
1 | file="/var/www/runoob/test.sh" |
4.7 linux shell “”(())” 双括号运算符 、 “[[]]”、”[]”、
4.7.1 “”(())”
(())只能计算整数
特变逻辑运算符”[]”使用时候,必须保证运算符与算数 之间有空格。 四则运算也只能借助:let,expr等命令完成。 今天讲的双括号”(())”结构语句,就是对shell中算数及赋值运算的扩展。使用双括号,在比较过程中使用高级数学表达式
符号 | 描述 |
---|---|
val++ | 后增 |
val– | 后减 |
++val | 先增 |
–val | 先减 |
! | 逻辑求反 |
~ | 位求反 |
** | 幂求反 |
<< | 左位移 |
>> | 右位移 |
&& | 逻辑和 |
1 | 语法: |
扩展逻辑运算
1 | a=1; |
有了双括号运算符和三个[[]],[],test 逻辑运算,那么let,expr 都可以抛到一边了。
4.7.2 “[[]]”
- 双方括号提供了字符串比较的高级特性。
- 括号中可以定义一些正则表达式来匹配字符串
- 注意不是所有的shell都支持双方括号!
1 | if [[ $USER == s* ]] |
注意:[[]] 运算符只是[]运算符的扩充。能够支持<,>符号运算不需要转义符,它还是以字符串比较大小。里面支持逻辑运算符:|| && ,不再使用-a -o
4.7.3 “[]”
- 方括号定义了测试条件。
- 第一个方括号后和第二个方括号前都要加一个空格,否则会报错。
- 方括号主要包括4类判断:数值比较(4.3)、文件比较(4.6)、符合条件比较(4.4)
字符串比较
比较 | 描述 |
---|---|
str1 = str2 | 检查str1是否和str2相同 |
str1 != str2 | 检查str1是否和str2不同 |
str1 < str2 | 检查str1是否比str2小 |
str1 > str2 | 检查str1是否比str2大 |
-n str1 | 检查str1的长度是否非0 |
-z str1 | 检查str1的长度是否为0 |
1 | if [ $USER != $testuser ] then |
在[] 表达式中,常见的>, <需要加转义字符,表示字符串大小比较,以acill码 位置作为比较。
不直接支持<, >运算符,还有逻辑运算符|| , && 它需要用-a[and] –o[or]表示
4.7.4 “test”
test可用于测试表达式,支持测试的范围包括:字符串比较,算术比较,文件存在性、属性、类型等判断。例如,判断文件是否为空、文件是否存在、是否是目录、变量是否大于5、字符串是否等于”longshuai”、字符串是否为空等等。在shell中,几乎所有的判断都使用test实现。
1 | test 1 = 1 && echo 'ok' |
注意:所有字符 与逻辑运算符直接用“空格”分开,不能连到一起。test 1=1就是错误的!
4.7.4 后三者的区别
1 | type [ [[ test |
[
和test
是相等的。
1 | test -f settings.py && echo True |
[] 和 [[]]区别:
1 | [ 2 < 1 ] && echo True || echo False |
总结:
使用[[ … ]]条件判断结构,而不是[ … ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,
但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]]
如果不使用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]
bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。
1 | [ !(pip list | grep pip) ] && echo True || echo False |
4.8 shell 中| && || () {} 用法以及shell的逻辑与或非
4.8.1 | 运算符
管道符号,是unix一个很强大的功能,符号为一条竖线:”|”。
用法:
command 1 | command 2
他的功能是把第一个命令command 1执行的结果作为command2的输入传给command ex:
1 | ls -s|sort -nr |
4.8.2 && 运算符
1 | 格式 |
- 命令之间使用 && 连接,实现逻辑与的功能。
- 只有在 && 左边的命令返回真(命令返回值 $? == 0),&& 右边的命令才会被执行。
- 只要有一个命令返回假(命令返回值 $? == 1),后面的命令就不会被执行。
- 示例1中,cp命令首先从root的家目录复制文件文件anaconda-ks.cfg到 /data目录下;执行成功后,使用 rm 命令删除源文件;如果删除成功则输出提示信息”SUCCESS”。
1 | cp anaconda-ks.cfg /data/ && rm -f anaconda-ks.cfg && echo "SUCCESS" |
4.8.3 || 运算符
格式
1 | command1 || command2 |
||则与&&相反。如果||左边的命令(command1)未执行成功,那么就执行||右边的命令(command2);或者换句话说,“如果这个命令执行失败了||那么就执行这个命令。
- 命令之间使用 || 连接,实现逻辑或的功能。
- 只有在 || 左边的命令返回假(命令返回值 $? == 1),|| 右边的命令才会被执行。这和 c 语言中的逻辑或语法功能相同,即实现短路逻辑或操作。
- 只要有一个命令返回真(命令返回值 $? == 0),后面的命令就不会被执行。
1 | echo $BASH |grep -q 'bash' || { exec bash "$0" "$@" || exit 1; } # 系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变。因此,可以这样认为,exec系统调用 |
5、遍历
5.1 遍历的方式
Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for、while和until。while循环和for循环属于“当型循环”,而until属于“直到型循环”。循环控制符:break和continue控制流程转向。
5.1.1 for循环
for循环有三种结构:一种是列表for循环,第二种是不带列表for循环。第三种是类C风格的for循环。
(1)、列表for循环
1 | for varible1 in {1..5} |
do和done之间的命令称为循环体,执行次数和list列表中常数或字符串的个数相同。for循环,首先将in后list列表的第一个常数或字符串赋值给循环变量,然后执行循环体,以此执行list,最后执行done命令后的命令序列。
Sheel支持列表for循环使用略写的计数方式,1~5的范围用{1..5}表示(大括号不能去掉,否则会当作一个字符串处理)。
Sheel中还支持按规定的步数进行跳跃的方式实现列表for循环,例如计算1~100内所有的奇数之和。
(2)、列表for循环 设置步长
1 | sum=0 |
通过i的按步数2不断递增,计算sum值为2500。同样可以使用seq命令实现按2递增来计算1~100内的所有奇数之和,for i in $(seq 1 2 100),seq表示起始数为1,跳跃的步数为2,结束条件值为100。
for循环对字符串进行操作,例如通过for循环显示当前目录下所有的文件。
1 | for file in $( ls ) |
for通过命令行来传递脚本中for循环列表参数:
1 | echo "number of arguments is $#" |
**解释:**linux中shell变量$#,$@,$0,$1,$2的含义解释
1 | linux中shell变量$#,$@,$0,$1,$2的含义解释: |
(3)、不带列表for循环
由用户制定参数和参数的个数,与上述的for循环列表参数功能相同。
1 | shell: |
(4)、类C风格的for循环
1 | for((integer = 1; integer <= 5; integer++)) |
for中第一个表达式(integer = 1)是循环变量赋初值的语句,第二个表达式(integer <= 5)决定是否进行循环的表达式,退出状态为非0时将退出for循环执行done后的命令(与C中的for循环条件是刚好相反的)。第三个表达式(integer++)用于改变循环变量的语句。
Sheel中不运行使用非整数类型的数作为循环变量,循环条件被忽略则默认的退出状态是0,for((;;))为死循环。
类C的for循环计算1~100内所有的奇数之和。
1 | sum=0 |
5.1.2 while循环
也称为前测试循环语句,重复次数是利用一个条件来控制是否继续重复执行这个语句。为了避免死循环,必须保证循环体中包含循环出口条件即表达式存在退出状态为非0的情况。
1)计数器控制的while循环
1 | sum=0 |
指定了循环的次数50,初始化计数器值为1,不断测试循环条件i是否小于等于100。在循环条件中设置了计数器加2来计算1~100内所有的奇数之和。
2)结束标记控制的while循环
设置一个特殊的数据值(结束标记)来结束while循环。
1 | echo "Please input the num(1-10) " |
例:通过结束标记控制实现阶乘的操作
1 | echo "Please input the num " |
3)标志控制的while循环
使用用户输入的标志值来控制循环的结束(避免不知道循环结束标志的条件)
1 | echo "Please input the num " |
标志控制的while循环求1~n的累加和,循环变量值小于100执行else累加同时循环变量加1,直到循环变量值等于100将标志值设置为1,并输出。
标志控制的while循环与结束标记控制的while循环的区别是用户无法确定无法确定结束标志,只能程序运行后确定结束标志。两者也可以相互转化。
4)命令行控制的while循环
使用命令行来指定输出参数和参数个数,通常与shift结合使用,shift命令使位置变量下移一位($2代替$1、$3代替$2,并使$#变量递减),当最后一个参数显示给用户,$#会等于0,$*也等于空。
1 | echo "number of arguments is $#" |
5.1.3、until循环
until命令和while命令类似,while能实现的脚本until同样也可以实现,但区别是until循环的退出状态是不为0,退出状态是为0(与while刚好相反),即whie循环在条件为真时继续执行循环而until则在条件为假时执行循环。
1 | i=0 |
5.1.4、循环嵌套
一个循环体内又包含另一个完整的循环结构,在外部循环的每次执行过程中都会触发内部循环,for、while、until可以相互嵌套。
(1)嵌套循环实现九九乘法表
1 | for (( i = 1; i <=9; i++ )) |
(2)for循环嵌套实现*图案排列
1 | for ((i=1; i <= 9; i++)) |
5.1.5、循环控制符break和continue
若须退出循环可使用break循环控制符,若退出本次循环执行后继续循环可使用continue循环控制符。
(1)break
在for、while和until循环中break可强行退出循环,break语句仅能退出当前的循环,如果是两层循环嵌套,则需要在外层循环中使用break。
1 | sum=0 |
(2)continue
在for、while和until中用于让脚本跳过其后面的语句,执行下一次循环。continue用于显示100内能被7整除的数。
1 | m=1 |
5.1.6、select结构
select结构从技术角度看不能算是循环结构,只是相似而已,它是bash的扩展结构用于交互式菜单显示,功能类似于case结构比case的交互性要好。
(1)select带参数列表
1 | echo "What is your favourite color? " |
(2)select不带参数列表
该结构通过命令行来传递参数列表,由用户自己设定参数列表。
1 | echo "What is your favourite color? " |
5.2数组遍历
1 | names=(dong,"wen",yu) |
5.2.1 标准的for循环
1 | for(( i=0;i<${#array[@]};i++)) |
5.2.2 for … in
1 | for element in ${array[@]} |
5.2.3 While循环法
1 | i=0 |
6、注释
1 | 1、单行 |
1 | https://www.cnblogs.com/zeweiwu/p/5485711.html |
7、输入与输出
7.1 输入/输出重定向
大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。
重定向命令列表如下:
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |
需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
1、输出重定向
重定向一般通过在命令间插入特定的符号来实现。特别的,这些符号的语法如下所示:
1 | command1 > file1 |
上面这个命令执行command1然后将输出的内容存入file1。
注意任何file1内的已经存在的内容将被新内容替代。如果要将新内容添加在文件末尾,请使用>>操作符。
ex:执行下面的 who 命令,它将命令的完整的输出重定向在用户文件中(users):
1 | who > users |
2、输入重定向
和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:
1 | command1 < file1 |
这样,本来需要从键盘获取输入的命令会转移到文件读取内容。
注意:输出重定向是大于号(>),输入重定向是小于号(<)。
ex:接着以上实例,我们需要统计 users 文件的行数,执行以下命令:
1 | wc -l users |
也可以将输入重定向到 users 文件:
1 | wc -l < users |
注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。
1 | command1 < infile > outfile #同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中。 |
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
- 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
- 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
- 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
8、打印echo、printf
printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。
printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。
printf 命令的语法:
1 | printf format-string [arguments...] |
参数说明:
- format-string: 为格式控制字符串
- arguments: 为参数列表。
实例如下:
1 | printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg |
%s %c %d %f都是格式替代符
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中.2指保留2位小数。
9、流程控制
9.1 if else
1 | if condition |
1 | a=10 |
9.2 无线循环
1 | while : |
9.3 、case … esac
1 | case 值 in |
case 后为取值,值可以为变量或常数。
值后为关键字 in,接下来是匹配的各种模式,每一模式最后必须以右括号结束,模式支持正则表达式。
1 | site="runoob" |
10、函数
10.1函数定义
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
shell中函数的定义格式如下:
1 | [ function ] funname [()] |
说明:
- 1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
- 2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
下面的例子定义了一个函数并进行调用:
1 | demoFun(){ |
1 | funWithReturn(){ |
函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
10.2 函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
带参数的函数示例:
1 | funWithParam(){ |
注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
另外,还有几个特殊字符用来处理参数:
参数处理 | 说明 |
---|---|
$# | 传递到脚本或函数的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
10.3 函数返回值
有两种方式获取函数的返回值:
10.3.1 echo
在函数体中用echo语句,调用函数时用$(function_name param1 param2 … )获取函数中所有echo连在一起的值。
这种方式可以一下返回多个函数值,方式就是在函数体内有多个echo语句,如下:
1 | function test1() |
因为$()中可以执行linux 命令,而这里$()中的function_name param1 param2可以当成一条命令来看
10.3.2 return
在函数体中用return返回值,调用函数后,用echo 获取return返回的值。这种情况下return返回的必须是数字,否则会报错.一般用来相应函数执行状态码0成功,其它失败
1 | function test2() |
11、linux read解释
1 | read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] |
参数说明:
1 | -a 后跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分割符。 |
ex;
1 | read -sp "enter your password:" passward |
- 本文作者: 初心
- 本文链接: http://funzzz.fun/2021/01/04/shell/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!