Shell是用户态进行高效,安全访问Linux内核态的一个中间桥梁,是一个应用程序,同时是一个可编程的应用程序(也叫解析器),这种编程的语言是脚本语言(Shell 脚本,由解析器解析运行的语言);和音乐播放器一样(酷狗,QQ音乐,网易云),Shell这个解析器也有很多类型:sh、bash、csh、tcsh、ash;在X86服务器平台我们基本都是使用bash,bash也是Linux原生支持的解析器,由GNU组织开发,兼容sh(这意味着针对 sh 编写的 Shell 代码可以不加修改地在 bash 中运行);但是在嵌入式Linux的平台上,出于可移植性考虑,我们使用sh的规范。 1 基本语法1.1 第一个程序Shell脚本的相关代码我们放在~/workspace/basics/shell这个目录下。 Shell脚本的命名方式是以.sh为后缀的文件,比如test.sh;运行方式有两种,一种是通过解析器:sh test.sh的方式,另一种是给文件加可执行权限,然后直接运行:chmod +x test.sh , ./test.sh。 Shell脚本的开头需要包含一个基本说明:#!/bin/sh,除了这一句,注释需要以#号开头,如下例子:
脚本是解析运行的语言,不需要编译,直接运行:
1.2 日志输出为了区分输出信息的重要性,我们对echo这个命令进行封装,使其能输出不同颜色的日志,达到区分重要性的作用,代码如下:
我们给echo封装出两个接口,一个是:LOGD,一个是LOGE,用来输出不同颜色的日志;说明一下,这个地方用到了函数的概念,我们暂时忽略,后面会讲到,这里用法和echo是一样的。 运行如下:
1.3 变量定义变量时不需要指明类型,直接赋值就可以,注意变量和值之间不能有空格,不然运行会出错;命名只能使用英文字母,数字和下划线,首个字符不能以数字开头,基本会用到的变量类型就两种:数值 和 字符串:
使用一个定义过的变量,只要在变量名前面加美元符号即可:
其中花括号是可选的,也就是说可以用 $value,$string来表示变量,但是我们用的时候把花括号加上形成好习惯,不然不完全熟悉shell语法在一些多变量连接时会出问题。 在Shell中,变量类型可以分为全局变量和局部变量,不加任何修饰的情况下都是全局变量;局部变量需要加上local进行声明,且只用在函数中:
Shell 也支持将命令的执行结果赋值给变量,基本写法(推荐第二种): variable=`command`
variable=$(command)
运行结果:
1.4 分支控制ifelse格式结构如下,condition表示条件,coding是我们的代码逻辑:
例子如下,我们判断变量value的值是否等于,大于或者小于100:
ifelse的表达式可以归纳为三种:文件表达式,整型表达式和字符串表达式 文件表达式: if [ -f file ] 如果文件存在 if [ -d ... ] 如果目录存在 if [ -s file ] 如果文件存在且非空 if [ -r file ] 如果文件存在且可读 if [ -w file ] 如果文件存在且可写 if [ -x file ] 如果文件存在且可执行 整数变量表达式: if [ int1 -eq int2 ] 如果int1等于int2 if [ int1 -ne int2 ] 如果不等于 if [ int1 -ge int2 ] 如果>= if [ int1 -gt int2 ] 如果> if [ int1 -le int2 ] 如果<= if [ int1 -lt int2 ] 如果< 字符串变量表达式: If [ $a = $b ] 如果string1等于string2 if [ $string1 != $string2 ] 如果string1不等于string2 脚本运行结果:
1.5 for循环
当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值,命令可为任何有效的shell命令和语句。
运行如下:
可以看到,在for循环的in列表中,既可以是数值,也可以是字符串,还可以是表达式。 1.6 while循环格式如下: while condition
do
command
done
比如要判断一个数值如果小于5,就每次自加1,大于等于5循环终止:
运行结果:
如果需要无限循环可以这样写:
如果在循环中我们想要退出循环的逻辑,可以用break关键字来退出循环;对于for循环,break也一样可以打断的。 1.7 case分支语句Shell case语句为多选择语句;可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下: case var in match1) command.. ;; match2) command.. ;; *) command.. ;; esac 比如我们判断变量var的颜色例子,如下:
如果var不在green,blue,red中,那么会进入到*)中,表示其他的都没有被成功匹配到;in后面的列表中可以是数值也可以是字符串列表,该脚本的运行结果如下:
1.8 循环控制和C语言中的for/while一样,Shell中也可以用continue和break来控制for循环或者while循环,且含义是一样的,break命令允许跳出所有循环,continue则重新开始循环。比如下面例子:
测试结果:
1.9 变量运算符Shell中变量间的运算表达式基本记住一种即可:$((表达式));运算符一般有如下的几种类型:加(+),减(-),乘(*),除(/),求余(%)。 比如下面这个例子:
运行结果如下:
2 函数2.1 基本格式及调用linux shell 可以用户定义函数,然后在shell脚本中可以随便调用,shell中函数的定义格式如下:
函数名() { action;
[return int;] } 函数可以带返回值,写法是return int; 取值范围是0~255,注意只能返回整数;也可以不用返回值。调用的方式是在脚本中直接填写函数名即可,比如先前我们用到的日志输出接口LOGD和LOGE。 比如我们实现一个函数完成从1到10 的累加;需要补充说明的是:返回值会被存储在一个 $? 中:
程序运行结果:
2.2 函数参数在Shell脚本中,调用函数时可以向其传递参数,在函数内部,通过 ${x} 的形式来获取参数的值,例如,${1}表示第一个参数,${2}表示第二个参数,以此类推,当x小于10时,花括号可以省略。函数可以通过 $# 来获得参数的个数;还需要补充一个是 $* ,$*表示整个参数列表(可以用来不同函数间的传递):
运行该脚本,结果如下,上面代码中斜杆是对特殊字符的转义:
2.3 脚本传参运行脚本的时候,可以向脚本传递一串参数,参数的数量,表达方式和函数的传参是一致的,例子如下:
只不过是把参数放在最外层(不是函数里面),该脚本运行结果如下:
当然我们也可以把这个参数列表 $* 直接传递给函数做参数,然后在函数当中去做解析和应用。 ========================================================================================================================== 到这里基本的Shell脚本基础内容就学习完啦,是否很简单!!
如果觉得对您有帮助并想进一步深入学习交流可以扫描以下微信二维码或加入QQ群:928840648
欢迎共同学习成长,有一群爱学习的小伙伴一起勉励!!加油!!也可点击
笔者基于嵌入式系统框架内容如下整理编辑:
|