文章目录
前言
Linux的大多数情况都是在终端模式下,以命令行进行指令操作。比如之前树莓派的教程中,对一些文件进行配置,用到sudo nano xxx
的指令,然后进入一个文本进行编辑,这是命令的方式,大概就是我这边输入一条指令,系统运行一条指令。在后面涉及到我想要对QtCreator生成的Release版本进行打包发布这种项目需求,就需要编写一个系统性的指令文档,让系统能够一次执行。shell脚本应运而生。
本篇文章记录的是shell脚本的最常用的一种脚本bash
。
1. 变量
类似于C语言的教程,上来先介绍变量。C语言中的变量类型有很多,比如int
,char
,float
,double···等等
。比如我们在C语言中声明一个变量并为它赋值,那么系统会为他分配内存中的一块空间,我们通过声明的变量来对这个空间进行访问。而bash中虽然也有变量,但变量只能存储文本,有点类似于C的宏定义。
1.1 赋值
1.1.1 基本赋值
bash和C语言一样,都是用一个=
来进行赋值。
例如:var=test
这句话的意思就是把名为test的文本存入名为var的变量。
但是这里和C语言有个不同个地方在于=
的左右两遍存不存在空格的情况。
在C语言中,我可以这样写char a = 't'
,我们可以看到这里在=
的两边存在空格,但是在C语言的编辑器里面表达的意思依然是给一个字符类型的变量a
赋予值 t
。
这种情况在bash中却不接受,即在bash脚本中=
的左右两侧是不存在空格的,如果给变量赋值的值存在空格,那需要用单引号或者双引号来包裹文本。
例如:var='hello world'
或者var="hello world"
1.1.2 其他赋值
c语言中我们在使用函数对某一个变量进行了运算,需要把运算后的值返回给一个新的变量,那么上面这种直接赋值的方式就有点不太适合。
在bash中可以通过``
这个符号,把一个命令输出的文本直接赋予一个变量。
例如:现有一个库函数为add,返回的是一个最终结果。我定义一个变量sum来接收add函数的值。
sum=`add`
还可以把已经赋值的变量赋值给另一值,例如:var1=$var
类似于C语言在scanf,想通过用户输入的方式给变量赋值。在bash中可以用read
命令。
例如:read var
输入上面指令后,在键盘输入你想要赋值的值,比如hello,接着按下回车键。
那么var
的值就变成了hello
1.2 引用变量
1.2.1 查看变量
在bash中,我们可以通过在变量前面添加符号$
表示引用,换句话说就是取值操作。
例如:echo $var
命令就是输出var
变量的值。
在上面的read指令中,给var赋值之后,我们可以通过我们可以通过指令 echo var
来查看var
的值。
1.2.2 变量范围
$符号后面跟着的变量名,但如果我们想变量名加文本一起进行输出或者赋值操作呢。
例如:echo $nameIsMe
这里我们只给name
变量赋值为Edwinwzy
,上面的命令应该是输出EdwinwzyIsMe
,但是系统实际上会把它归为输出变量为nameIsMe
的值。这就与我们想要的输出发送了冲突。
为解决上面的问题,我们的变量进行引用的时候都需要用{}
进行框定范围,在大括号里面的标识变量,一般用法就变成echo ${name}IsMe
,这样才会输出我所需要的效果:EdwinwzyIsMe
。
1.2.3 Tips
如果我们输出的时候采用单双引号,在单引号里面放了$var
,那么输出的时候不会输出var变量的具体值,而会把它当做一个文本输出。只有在双引号的里面才会输出它的值。
2. 数学运算
在一开始写到bash时,说明bash的变量没有类型,都是按照文本形式进行保存。所以各种运算符号:+-*/
都不会像C一样很方便的运算。
C里面可以这么写:int a=1+1;
但是bash里面这写:a=1+1
就等价于a变量的值为1+1,即一个文本的形式,它并不会进行运算。
如果想要运算,bash中是通过$(())
来进行运算的。
还是刚才的例子,我们可以通过这样的写法进行运算后赋值:a=$((1+1))
。
运算就会有优先级,优先级从高到低排序如下所示。
(1)乘方。(用**
表示)
(2)乘法、除法和求余。
(3)加法和减法。
当优先级相等时,bash按照从左向右的顺序来进行运算。当然,像数学中那样,括号中的内容将优先执行。
3. 简易bash脚本
3.1 return 0?
C语言中的函数一般我们最后都是return 0;这个用来表示程序正常运行完毕返回。起到一个返回码校验的作用。在Linux中也有类似的情况。
我们可以通过echo $?
来输出程序的返回码,正常运行的代码返回码为0,异常的非0。
在树莓派的博客中,涉及到开机自启的情况,我们需要修改rc.local
文件。在这个文件里有一些代码,我们设置的自启软件的目录代码在exit 0前面,这样的作用其实就是在程序结束前运行。如果放在exit 0后面,其实我们设置是不生效的。
3.2 简单脚本
这个小节我们编写一个helloworld简单脚本。
通过touch指令新建一个脚本:touch test.sh
可以使用nano指令进行编写:nano test.sh
在脚本内部,开头第一行一般都会写#!/bin/bash
。这句话说明了该脚本使用的Shell,即/bin/bash路径的bash程序。
接着添加新的指令echo "hello world"
脚本内代码如下:
#!/bin/bash
echo "hello world"
通过./test.sh
运行,输出hello world。
也可以通过变量的方式进行输出,这里设var的值为hello world
脚本内代码如下:
#!/bin/bash
echo $var
为什么我这里编写的两个脚本没加exit 0
,因为在脚本的末尾加一句exit 0并不必要。一个脚本如果正常运行完最后一句,会自动返回代码0。在脚本运行后,可以通过$?
变量查询脚本的返回代码。
如果在脚本中部出现exit命令,那么脚本会直接在这一行停止,并返回该exit命令给出的返回代码,比如下面的代码。
#!/bin/bash
echo $var #var值为hello world
exit 1
echo $name #name值为Edwinwzy
这个脚本就只会输出hello world
,并且返回码为1。不会输出name的值。