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