shell基础
一、文件的创建与执行
1.创建文件first.sh,写入如下内容:
2.执行该文件:
执行该文件时,我们会发现,,所执行文件并没有成功,而且会显示有关权限的县官问题。
注意:一定要写成./first.sh,而不是first.sh,运行其他二进制程序也是一样的,直接写成first.sh,linux系统会去PATH里寻找有没有叫first.sh的,二只有/bin,/sbin,/usr/bin,/usr/sbin等在PATH里,自己的当前目录通常不在PATH里,所有写成first.sh是会找不到的命令的,要用./first.sh告诉系统说,就在当前目录找。
3.对显示结果进行分析,发现是缺少执行权限,使用chmod对带文件添加权限并执行:
4.解释执行本质原理
a)使用chmod u+x first.sh会fork一个子进程并调用exec执行./first.sh这个程序,exec系统调用应该把子进程代码段替换成./first.sh程序的代码段,并从它的_start开始执行。
b)然而first.sh是一个文本文件,,根本没有代码段和_start函数!如果要执行的是一个文本文件,并且第一行用shebang指定了解析器,则用解析器程序的代码替换当前进程,并且从解析器的_start开始执行,而这个文本文件被当作命令行参数传给解析器。
二、shell执行过程
1.交互Shell(bash)fork/exec一个子shell用来执行脚本,父进程bash等待子进程sh终止;
2.sh读取脚本中的cd .. 命令,调用相应的函数执行内建命令,改变当前目录为上一级目录;
3.sh读取脚本中的ls命令,fork/exec这个程序,列出当前工作目录下的文件,sh等待ls终止;
4.ls终止后,sh继续执行,读取脚本文件末尾,sh结束;
5.sh终止后,bash继续执行,打印提示符等待用户输入。
特殊例子1:
解释:脚本执行cd命令,发现回显信息当前所处的目录发生改变,但实际上,真实目录并没有发生改变。这个也很好解释,毕竟要创建子进程来解释脚本。
特殊例子2:
解释:直接命令执行cd命令,发现父bash的工作目录发生了改变!说好的创建子进程呢?归根结底,执行命令,不一定要创建子进程!这些不需要创建子进程的命令。叫做shell的内置命令,有父bash直接执行。
特殊例子3:
解释:用source修饰脚本,脚本的执行影响到了父bash!source命令是shell的内建命令,这种方式也不会创建子shell,而是直接在交互shell下执行脚本中的命令。
三、shell中的变量
注:shell变量不需要提前定义,或者不牵扯到定义一说,需要时直接受使用即可。
1.赋值和命名规则
命名规则:
a)首个字母必须为字母;
b)中间不能有空格,可以使用下划线;
c)不能使用标点符号;
d)不能使用bash中的关键字。
2.所有变量不需要先定义后使用,而是直接使用:
注:变量名和等号直接不能有空格!否则会被shell解释成命令和命令行参数。
四、shell中的基本操作
1.字符串的拼接
注:
1.如果变量是一个新了变量名,二这个变量并没有被使用过,则显示为空;
2.变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界。推荐给所有变量都加上花括号,这是一个好的编程习惯。
2.只读变量
使用readonly命令可以将变量定义为只读变量,只读变量不能被改变:
3.删除变量
注:
1.被删除了变量,内容将被清空,一般也是不在被使用的变量需要unset;
2.unset不能删除只读变量
4.本地变量与环境变量
注:
1.本地变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量;
2.环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量;
3.shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行。
4.一个变量定义后仅存在与当前shell进程 ,它是本地变量,用export命令可以把本地变量导出为环境变量。
5.提取与查找子字符串
6.文件名替换
1.通配符*:匹配0个或多个任意字符;
b)?:匹配一个任意字符;
c)[若干字符]:匹配方括号中的任意一个字符的一次出现
注:
1.由反引号括起来的也是一条命令,shell先执行该命令,然后将输出结果立即替换到当前命令行中