1、shell简介
shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。
2、shell的工作原理
系统初启后,核心为每个终端用户建立一个进程去执行Shell解释程序。它的执行过程基本上按如下步骤:
(1)读取用户由键盘输入的命令行。
(2)分析命令,以命令名作为文件名,并将其它参数改造为系统调用execve( )内部处理所要求的形 式。
(3)终端进程调用fork( )建立一个子进程。
(4)终端进程本身用系统调用wait4()来等待子进程完成(如果是后台命令,则不等待)。当子进程运 行时调用execve(),子进程根据文件名(即命令名)到目录中查找有关文件(这是命令解释程序构 成的文件),将它调入内存,执行这个程序(解释这条命令)。
(5)如果命令末尾有&号(后台命令符号),则终端进程不用系统调用wait4()等待,立即发提示符,让 用户输入下一个命令,转⑴。如果命令末尾没有&号,则终端进程要一直等待,当子进程(即运行 命令的进程)完成处理后终止,向父进程(终端进程)报告,此时终端进程醒来,在做必要的判别 等工作后,终端进程发提示符,让用户输入新的命令
3、程序
程序就是指令加数据,起功能就是通过指令去加工指定的数据,并输出结果;
程序编写分为两种:
面向过程:以指令为中心
面向对象:以数据为中心
bash属于面向对象的编程语言;bash有三种控制执行方式
顺序执行:逐个执行
选择执行:只执行其中一个分支
循环执行:一段代码要执行0,1或多遍
4、程序执行的分类
程序按照编译方式来可以分为两类
编译执行:预处理-->编译-->汇编-->链接;事先完成,结果:二进制程序文件
如是用C, C++等语言开发的程序
解释执行:由解释器全程参与运行过程,每次读取一行,运行一行;
Python:编程库
程序控制结构,调用编程库完成程序编写;
库文件:功能模块,在编程中可调用;通过其API;
Bash:编程
程序控制结构,调用机器上命令程序文件进行程序编写;
外部命令:各应用程序提供;
5、变量
变量就是内存中存放可变量的空间;
bash的变量分为:
环境变量:有效范围是当前shell进程及其子进程
本地变量:当前进程
局部变量:某个函数的执行过程
位置参数变量:在脚本中引用传递给脚本的参数;在函数中引用传递给函数的参数;
特殊变量:$?, $*, $@, $#, $$
变量的类型(bash默认是字符型)
数值型
整数
浮点数
字符型
ASCII
如;120
数值型则为120
字符型则为1、2、0
bash的变量是不严格区分类型,也不必事先声明
6、本地变量:
name=value
name: 变量名
=:赋值符号
value:值
变量名:只能包含数字、字母和下划线;且不能以数字开头;
引用变量:${name}, $name
引用:
弱引用: "", 其内部的变量引用会被替换为变量值;
强引用:'',其变量的变量引用会保持原有字符;
命令引用:`COMMAND`, $(COMMAND),引用命令的执行结果;
声明为整型:
declare -i name[=value]
let name=value
查看所有变量:set
生命周期:
创建
销毁:
自动销毁:shell进程终止;
手动销毁:unset name
7、环境变量:
被“导出”的本地变量
export name[=value]
declare -x name[=value]
查看所有环境变量:env, printenv, export
销毁:
unset name
8、脚本:文本文件
运行脚本:事实上是运行一个bash进程,此进程负责从脚本文件中读取一个执行逻辑,而后由bash进程负责解析并运行此逻辑;
启动脚本:
(1) # bash /PATH/TO/SCRIPT_FILE
(2) 一个执行权限,
# ./PATH/TO/SCRIPT_FILE
shebang:
#!/bin/bash
第一行:顶格给出shebang
注释行:#
bash的常用选项:
-n: 检查脚本中的语法错误;
-x:调试执行脚本;
9、命令状态结果:
bash进程用于追踪执行的命令成功与否的状态:
0: 成功
1-255:失败
特殊变量:
$?:上一条命令的执行状态结果;
布尔型:
“真”:成功
“假”:失败
自定义脚本的状态结果:
exit [n]
注意:脚本中任何位置执行了exit命令即会终止当前shell进程;
10、条件测试:
界定程序执行环境;
(1) 根据运行的命令的状态结果;
(2) 测试表达式
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
整数测试:隐含着做数值大小比较,所以不要给变量引用加引用;
$A -gt $B:是否大于;是则为“真”,否则为“假”;
$A -ge $B: 是否大于等于;
$A -lt $B:是否小于;
$A -le $B: 是否小于等于;
$A -eq $B: 是否等于;
$A -ne $B:是否不等于;
[root@pizi ~]# cat test.sh #!/bin/bash declare -i x=10 declare -i y=100 echo "x=$x" echo "y=$y" echo "判断上面两个数值得大小,是则输出0,否则输出非0" echo "$x -gt $y:x是否大于y" test $x -gt $y;echo $? echo "$x -ge $y:x是否大于等于y" test $x -ge $y;echo $? echo "$x -lt $y:x是否小于y" test $x -lt $y;echo $? echo "$x -le $y:x是否小于等于y" test $x -le $y;echo $? echo "$x -eq $y;x是否等于y" test $x -eq $y;echo $? echo "$x -ne $y;x是否不等于y" test $x -ne $y;echo $? [root@pizi ~]# [root@pizi ~]# bash test.sh x=10 y=100 判断上面两个数值得大小,是则输出0,否则输出非0 10 -gt 100:x是否大于y 1 10 -ge 100:x是否大于等于y 1 10 -lt 100:x是否小于y 0 10 -le 100:x是否小于等于y 0 10 -eq 100;x是否等于y 1 10 -ne 100;x是否不等于y 0 [root@pizi ~]#
字符串测试:ASCII数值越大,字符比较时其值越大;
"$A" > "$B":是否大于;
"$A" < "$B":是否小于;
"$A" == "$B":是否等于;
"$A" != "$B":是否不等于;
-z "$A":是否为空;空则为“真”,否则为“假”
-n "$A":是否不空;不空则“真”,空则为“假”
注意:应该使用[[ EXPRESSION ]]
[root@pizi ~]# cat test.sh #!/bin/bash A=hello B=world echo "A is $A" echo "B is $B" echo "测试字符串A,B,是则为“真”(0),否则为“假”(非零);" echo ""$A" > "$B":是否大于;" [[ "$A" > "$B" ]];echo $? echo ""$A" < "$B":是否小于;" [[ "$A" < "$B" ]];echo $? echo ""$A" == "$B":是否等于;" [[ "$A" == "$B" ]];echo $? echo ""$A" != "$B":是否不等于;" [[ "$A" != "$B" ]];echo $? echo "-z "$A":是否为空;空则为“真”,否则为“假”" [[ -z "$A" ]];echo $? echo "-n "$A":是否不空;不空则“真”,空则为“假”" [[ -n "$A" ]];echo $? [root@pizi ~]# bash test.sh A is hello B is world 测试字符串A,B,是则为“真”(0),否则为“假”(非零); hello > world:是否大于; 1 hello < world:是否小于; 0 hello == world:是否等于; 1 hello != world:是否不等于; 0 -z hello:是否为空;空则为“真”,否则为“假” 1 -n hello:是否不空;不空则“真”,空则为“假” 0
文件测试:测试文件的存在性以及属性;
-e $file: 是否存在;存在则为“真”,否则为“假”;
-a $file: 同上;
-f $file:文件是否存在且为普通文件;
-d $file:文件是否存在且为目录;
-h $file:是否存在且为符号链接文件;
-L $file: 同上
-b $file:是否存在且为块设备文件;
-c $file:是否存在且为字符设备文件;
-S $file:是否存在且为套接字文件;
-p $file: 是否存在且为管道文件;
-r $file: 当前用户对文件是否拥有读权限;
-w $file:当前用户对文件是否拥有写权限;
-x $file:当前用户对文件是否拥有执行权限;
-u $file:文件是否拥有SUID权限;
-g $file:文件是否拥有SGID权限;
-k $file:文件是否拥有sticky权限;
-O $file: 当前用户是否为指定文件的属主;
-G $file: 当前用户是否为指定文件的属组;
双目操作符:
$file1 -nt $file2: file1是否新于file2, file1的最近一次的修改时间戳是否晚于file2的;
$file1 -ot $file2: file1是否旧于file2, file1的最近一次的修改时间戳是否早于file2的;
$file1 -ef $file2:file1与file2是否指向了同一个inode;测试二者是否为同一个文件的硬链接;
特殊设备:
/dev/null: 空,bit buckets,吞下所有数据,并直接丢弃;
/dev/zero:吐出一堆0;