shell脚本
一. shell脚本简介
1.1. shell语言
1.1.1. 编写shell脚本时使用的语言就是shell语言,又叫脚本语言。
1.1.2. 常用shell语言:sh、bash、csh、ksh、perl、python等
1.1.3. linux下最常用的脚本就是bash,我们学习也是以bash为主
1.2. shell脚本
a. shell程序是解释运行的,所谓解释运行就是说当我们执行一个shell程序时,shell解析器会逐行的解释shell程序代码,然后一行一行的去运行。(顺序结构)
b. 脚本程序不同c语言,脚本程序编写好后源代码即可直接运行(没有编译链接过程)
c. shell程序是文本格式的,只要是文本编辑器都可以。
1.3 运行shell脚本
1.3.1. shell程序运行的运行有多种方法,这里介绍三种方法:
a. ./xx.sh,和运行二进制可执行程序方法一样。这样运行shell要求shell程序必须具有可执行权限。chmod a+x xx.sh来添加可执行权限。
b. source xx.sh,source是linux的一个命令,这个命令就是用来执行脚本程序的。这样运行不需要脚本具有可执行权限。
c. bash xx.sh,bash是一个脚本程序解释器,本质上是一个可执行程序。这样执行相当于我们执行了bash程序,然后把xx.sh作为argv[1]传给他运行。
1.4. shell脚本有什么用
1.4.1. shell就是把以前命令行中键入执行的命令写成了程序。shell其实就是为了避免反复的在命令行下手工输入而发明的一种把手工输入步骤记录下来,然后通过执行shell脚本程序就能再次复述原来记录的手工输入过程的一种技术。例如当时创建交叉编译链工具链接符号时利用脚本自动创建
二. shell脚本语法规则
2.1. 变量
2.1.1. 变量定义和初始化。shell是弱类型语言(语言中的变量如果有明确的类型则属于强类型语言;变量没有明确类型就是弱类型语言),和C语言不同。在shell编程中定义变量不需要制定类型,也没有类型这个概念。
2.1.2. 变量定义时可以初始化,使用=进行初始化赋值。在shell中赋值的=两边是不能有空格的。
2.1.3. 变量赋值,变量定义后可以再次赋值,新的赋值会覆盖老的赋值
2.1.4. 变量引用。shell中引用一个变量必须使用$符号,$符号就是变量解引用符号。
a. 变量引用的时候可以$var,也可以${var}。这两种的区别是在某些情况下只能用${var}而不能简单的$var
b. $符号后面跟一个字符串,这个字符串就会被当作变量去解析。如果这个字符串本身没有定义,执行时并不会报错,而是把这个变量解析为空。
c. $var与${var}区别示例:
#!/bin/sh # test script var=abc echo $vardef echo ${var}def
2.2. shell脚本中无引用、单引号和双引号的区别
2.2.1 shell中使用字符串可以不加双引号或单引号,缺陷是不能输出"或者其他转义字符
2.2.2. shell中也可以使用单引号来表示字符串,也是直接使用的,如果字符串中有转义字符,字符并不会转义输出。
2.2.3. shell脚本中使用双引号表示字符串,则字符串中转义字符会进行转义
2.3. shell执行命令
2.3.1. 使用反引号把命令括起来执行即可
#!/bin/sh # test script var=`pwd` echo ${var}
2.4. shell中的选择分支结构
2.4.1. shell的if语言用法很多,在此只介绍常用的,其他感兴趣可以自己去百度
2.4.2. 表达式格式
if [表达式]; then xxx yyy zzz else xxx ddd uuu fi 示例: if [ -f file ] then echo "是一个普通文件" else echo "不是一个普通文件" fi
2.4.3. if的典型应用
a. 判断文件是否存在。(-f),注意[]里面前后都有空格,不能省略。
d. 判断目录是否存在 (-d)
c. 判断字符串是否相等("str1" = "str2"),注意用一个等号而不是两个
d. 判断数字是否相等(-eq)、大于(-gt)、小于(-lt)、大于等于(-ge)、小于等于(-le) 回忆一下在ARM裸机中讲述ARM汇编条件执行时,曾经用过这些条件判断的缩写。(eq就是equal,gt就是greater than,lt就是less than,ge就是greater or equal,le就是less or equal)
e. 判断字符串是否为空(-z)注意-z判断时如果变量本身没定义也是不成立(也就是说-z认为没定义不等于为空)
if [ "$SRCTREE" != "$OBJTREE" ] ; then mkdir -p ${OBJTREE}/include mkdir -p ${OBJTREE}/include2 cd ${OBJTREE}/include2 rm -f asm ln -s ${SRCTREE}/include/asm-$2 asm LNPREFIX="../../include2/asm/" cd ../include rm -rf asm-$2 rm -f asm mkdir asm-$2 ln -s asm-$2 asm else cd ./include rm -f asm ln -s asm-$2 asm fi
2.4.4. 逻辑与,或
a. 逻辑与&&和逻辑或||与简写的if表达式相结合。
b. 说明
[ "${BOARD_NAME}" ] || BOARD_NAME="$1" [ $# -lt 4 ] && exit 1 [ $# -gt 6 ] && exit 1
2.5. case语句
2.5.1. shell中的$# $1等内置变量的值不是不可变的,而是可以被改变,被shift指令改变。shift指令有点像左移运算符,把我们给shell程序的传参左移了一个移出去了,原来的$2变成了新的$1,原来的$#少了1个。
2.5.2. shell中的break关键字和C语言中意义相同(都是跳出)但是用法不同。因为shell中case语句默认不用break的,因此在shell中break只用于循环跳出。所以当while中内嵌case语句时,case中的break是跳出外层的while循环的,不是用来跳出case语句的。
三. shell中的循环结构
3.1. for循环
3.2. while循环
while [ $# -gt 0 ] ; do case "$1" in --) shift ; break ;; -a) shift ; APPEND=yes ;; -n) shift ; BOARD_NAME="${1%%_config}" ; shift ;; *) break ;; esac done
四. 其他
4.1. echo的创建和追加输入文件
4.1.1 在shell中可以直接使用echo指令新建一个文件,并且将一些内容传入这个文件中。创建文件并输入内容的关键就是>
4.1.2. 还可以使用echo指令配合追加符号>> 向一个已经存在的文件末尾追加输入内容。
4.2. shell程序的传参
4.2.1. shell程序本身也可以在调用时传参给他。在shell程序内部使用传参也是使用的一些特定符号来表示的,包括:
a. $#表示调用该shell时传参的个数。($#计数时只考虑真正的参数个数)
b. $0、$1、$2·····则依次表示传参的各个参数。
4.2.2. C语言:./a.out aa bb cc argc = 4, argv[0] = ./a.out, argv[1]是第一个有效参数····
4.2.3. shell:source a.sh aa bb cc $# = 3, $0是执行这个shell程序的解析程序的名字,$1是第一个有效参数的值,$2是第2个有效参数的值·····