目录
一、概念
二、简单创建脚本
三、shell语法
1.变量
2.环境变量
3.参数变量
4.条件
5.控制结构
if语句
elif语句
for语句
while循环
Until循环
case
四、脚本调用脚本
四、C程序调用脚本——exec替换
五、函数在shell内的使用
什么是shell?
shell是一个作为用户与Linux系统间接口的程序,它允许用户向操作系统输入需要执行的命令。
下图显示了shell(实际上是两种shell:bash、csh)和其他程序环绕在Linux内核的四周。
在大多数Linux发行版中,默认的shell程序/bin/sh实际上是对程序/bin/bash的一个连接。可以使用如下命令来查看bash的版本号
$ /bin/bash --version
如果想要切换到另一个shell(例如,bash不是你的系统中默认的shell ),你只需直接执行需要的shell程序(例如,/bin/bash)就可以运行新的shell并且改变命令提示符了。
1.创建脚本的后缀名为.sh
2.执行"./my.sh"系统发现是脚本文件后会帮助我们启动bash,达到和"bash my.sh"一样的结果
3.书写shell的规则与含义
如下是一个简单的shell编程,第一行是执行绝对路径下的bash,如果没有写系统会认为是默认的系统解释器,第3行是输出“hello shell”的内容,第5行exit命令的作用是保证脚本程序能够返回一个有意义的退出码。
下例是键盘输入并输出值显示。第3行是提示符输入,第4行是从键盘读取数据给line,第6行是printf输出line值。($的含义在下面第三板块变量内讲解)
如果想要换行的话,应加入\n,如下所示:
在本小结内包含了一下重要内容:
一些规则:
$?是上一句语句执行的结果
20行输出了19行的内容,21行输出20行,成功用0表示。
当一个shell脚本程序开始执行时,一些变量会根据环境设置中的值来进行初始化。这些变量通常用大写字母做名字,以便把他们和用户脚本程序里定义的变量区分开来,后者按惯例都用小写字母做名字。
下图是系统使用手册中列举的环境变量。
下图举例,输出参数变量hello 123,其中命令$1 ->第一个变量;$2 ->第2个变量,而对于第三个变量没有,所有$3输出为空。
如下示例对一级提示符修改为“^_^”:
恢复输入下面命令:
参数变量表如下所示:
除了使用echo命令来查看变量内容外,还可以使用read命令来读取
test或[命令
shell内bool布尔判断命令使用[或test。[在使用时还需要符号]结尾。
test命令可以使用条件类型归为3类:字符串比较、算术比较和文件有关的条件测试,如下图所示:
这个要结合上面条件讲的内容一起使用,使用规则如下:
if condition
then
statements
else
statements
fi
和else if相同用法,但是在shell内与if遵守相同规则
下面是一些具体的示例:
判断文件的类型:
此处,也体现了脚本文件的好处,如果用C语言去写势必更加复杂化。
对成绩进行判断等级示例:
echo "input"
read grade
if [ "$grade" -gt 100 || "$grade" -lt 0]
then
echo "error!\n"
if [ "$grade" -ge 80]
then
echo "A"
elif [ "$grade" -ge 70]
then
echo "B"
elif[ "$grade" -ge 60]
then
echo "C"
else
echo "D"
fi
我们可以使用for结构来循环处理一组值,这组值可以是任意的字符串集合。下面是它的语法:
for variable in values
do
statements
done
示例:
补充在脚本中对命令的使用,例如想要通过"ls"去输出当前路径下的文件内容然后赋值给str,但是直接str=ls这样的话,str的值是ls,并不是ls代表路径下的一系列文件。
此时,需要用“$()”或者“``”反引号去识别命令,如下就能得到我们想要的结果
也可以用for语句输出
while condition
do
statements
done
示例,对对小于10的值打印:
对i++
结果:
死循环
i<10,对i++,用while循环遍历i,如果i=5时跳过,其余i的值进行输出:
i<10,对i++,用while循环遍历i,如果i=5时退出,其余i的值进行输出:
对密码123进行验证,要求输入在3次以内:
条件满足时停下,未满足时持续执行
until condition
do
statements
done
示例
用until判断本地是否有“file.txt”文件
case variable in
pattern [ | pattern ] ...)statements;;
pattern [ | pattern ] ...)statements;;
...
esac
;; 结束
| 可要可不要的条件,对多个条件时的写法
示例:
输入是yes时输出yes,输入是no时输出no,其余的输出***
结果:
输入是yes或者y时(多个条件)输出yes
结果:
如果要任意大小写都能识别,用yes | y | Yes | YES...这样写就很复杂,为了让case的匹配功能更强大,可以使用如下的模式:
测试实例:
a.sh调用b.sh
需要用chmod a.sh去打开权限。
执行结果:
结果说明了一个问题:运行a.sh和b.sh的脚本的解释器,不是同一个解释器。如下代码进行说明:
那么能否让a.sh和b.sh在同一个解释器内?
可以的,用下面第5行/第6行的方式执行即可:
source/.+空格+b.sh路径:
此时,id相同,同一个解释器:
当前脚本中定义的变量想让其他脚本也能使用,即想要实现两脚本之间传参,需要通过下面3种方法实现:
脚本文件:
C程序:
子进程打印pid,并用execl替换调用脚本文件(系统自动判断是否是脚本,会自动调用命令解释器)
运行结果:
函数调用
先执行脚本文件再调用函数:
如果在阅读代码时,存在main()和main脚本时,也没有太大意义,其实也就是调用main()函数。
再举例脚本参数和调用函数参数的举例:
unset撤销变量
在解释器内的变量可以理解为不区分局部还是全局,因此可以被任意访问,所以需要unset这个功能撤销变量。如下代码示例对mystr赋值为hello,然后任意输出都能得到hello,输入“unset mystr”时就不能再输出了。
“local”在本函数内使用完参数之后,自动的unset,在函数外就无法再使用,避免忘记写unset
总结
1.怎么传参 ->直接写在函数后面
2.在函数内如何获得该参数 ->通过$1,$2....
3.怎么撤出变量 ->unset,local
内容暂时先到这里,剩下的下周补齐~