从事机顶盒开发以来,看到很多的Shell脚本,比如:开机启动脚本、系统升级脚本、软探针脚本、和系统编译脚本。这些脚本都是用shell语言开发,虽然在平时的需求开发和维护中会涉及到一定的脚本修改,但是一直没有系统的学习过shell语言。
所以本篇文章主要是记录学习shell过程中的笔记。同时也为巩固markdown语法,本篇笔记都是用markdown记录。
shell脚本语言
1、什么是shell脚本语言?
脚本语言是像剧本一样教计算机办某个事情的语言。
脚本语言其实就是短小的、用来让计算机自动化完成一系列工作的程序,这类程序可以用文本编辑器修改
不需要编译,通常解释运行。
2、运行shell脚本的两个方法
1 | chmod +x ./XXX.sh chmod后有空格 |
1 | /bin/sh XXX.sh |
3、shell变量
定义变量时,变量名不加$,如:
1 | your_name="runoob.com" |
使用定义过的变量时,只要在变量名前面加上$符号即可,如:
1 | your_name="qinjx" |
只读变量
1 | readonly myUrl |
删除变量
1 | unset myUrl |
变量类型
1、局部变量 :局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动程序不能访问变量
2、环境变量 :所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量
3、shell变量 :shell变量是由shell程序设置的特殊变量,shell变量中有一部风是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
4、shell字符串
字符串可以使用单引号也可以使用双引号,也可以不使用引号
强烈建议使用双引号
获取字符串长度
1 | string="adcg" |
多了个#
提取字符串
1 | string="runoob is a great site" |
5、shell数组
shell只支持一维数组
定义数组
用括号来表示数组,数组元素用“空格”符号分割开来,定义数组的一般形式为:
1 | array_name=(value0 value1 value2 value3) |
读取数组
1 | valuen=${array_name[1]} |
使用@符号可以获取数组中的所有元素,例如:
1 | echo ${array_name[@]} |
取得数组元素的个数
1 | length=${#array_name[@] |
取得数组单个元素的长度
1 | length=${#array_name[1]} |
6、shell传递参数
脚本内获取参数的格式为:0代表文件名,、$1代表参数1,$2代表参数2。
输出不存在的参数时结果为空
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有脚本传递的参数
$$ 脚本运行的当前进程号
7、shell基本运算符
无法把基本运算符结果false或者true当做字符串赋值给变量
进行四则运算时=两边不用空格,+两边一定要空格,四则运算一定要用双括号,比如
1 | num=(($num+1)) |
算数运算符
格式:expr a + b
表达式和运算符之间要有空格,例如2+2是不对的,必须写成2 + 2
完整的表达式要被``包含,注意这个字符不是常用的单引号
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字
假定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 -gt $b]返回true |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ |
布尔运算符
- ! 非运算
- -0或运算
- -a与运算
逻辑运算符
&&与运算
||或运算
字符串运算符
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -n $a ] 返回 true。 |
str | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
文件测试运算符
运算符 | 说明 | 举例 |
---|---|---|
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
8、shell流程控制
if语句
if语句
1 | if ···· |
if else语句
1 | if ···· |
if else-if else
1 | if ····· |
for循环
for循环格式为:
1 | for var in items items2 item3 .... itemsN |
while语句
while循环用于不断执行一系列命令,也用于从输入文件中读取数据,命令通常为测试条件,其格式为:
1 | while condition |
如果while condition涉及四则运算,需要使用双括号
单引号(‘’):括起来的字符作为普通字符
双引号(“”):括起来的字符,除 “$”, “\”, “`”和“``”保留其特殊功能外,其余仍作为普通字符
反引号(``):括起来的字串被解释为命令,shell首先执行该命令,并一他的标准输出结果例
9、shell函数
无参函数
shell中函数的定义格式如下:
1 | [ function ] funname [()] |
- 可以带function fun()定义,也可以直接fun()定义,不带任何参数
- 参数返回,可以显示加,return返回,如果不加,将以最后一条命令运行结果,作为返回值。
1 | #!/bin/bash |
1 | #!/bin/bash |
- 函数返回值在调用后通过$?来获取
- 所有函数在使用前必须定义,这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用,调用函数仅使用其函数名即可
有参函数
在shell中,调用函数时可以向其传递参数,,在函数内部,通过1表示第一个参数
1 | #!/bin/bash |
- 注意,
{10}
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
10、shell文件包含
和其他语言一样,shell也可以包含外部脚本,这样可以很方便的封装一些公用的代码作为一个独立文件
语法如下:
1 | . filename # 注意点号(.)和文件名中间有一空格 |
举例:
test1.sh
1 | #!/bin/bash |
test2.sh
1 | #!/bin/bash |
结果为:
1 | $ chmod +x test2.sh |
- 被包含的文件test1.sh不需要可执行权限