

##### 一个奇怪的现象:
#!/bin/bash
pwd cd .. pwd
按照上面的思路,上面的执行结果就是:
1. 显示当前的路径
2. 返回上一层
3. 再显示当前的路径(也就是上一层的路径)

结果:

路径是对的,可是执行之后,并没有返回上一层,这是什么情况?
下面就来介绍一下内置命令的概念以及Shell脚本执行的过程:
#### 内置命令 &Shell特点 & Shell脚本的执行过程:
---
##### 1. 内置命令:
如上的: cd ..
还有 : export echo
##### 2. Shell特点:
-
解释非编译型
-
弱类型
-
执行模式:交互式/批处理式
这里的弱类式的意思就是:变量类型不太会说明,不像C语言中有:char int string...
##### 3. Shell脚本的执行过程:
首先,我们都知道: 一个可执行的程序,是二进制,而这里是一个文本,那是怎么运行的?
#!/bin/bash
pwd cd .. pwd
一: 执行:bash ./test1.sh 后的过程 :
-
当前进程会fork(),子进程调用exec,然后将#!后面的解释器bash程序的代码替换当前进程
-
上面解释器的代码已经替换了子进程,下来就是一一去处理文本中的命令
-
子进程再去fork(),让孙子进程去处理第一行的命令
将第一行命令作为参数传给解释器(当前的解释器就类似于"函数")
-
上面只是处理了一行的命令,如果还有命令行,再去fork()
二 :从上面的执行过程,我们就可以知道,为什么会出现上面的奇怪现象?
因为:
上面的 cd.. 是在 子bash 中处理的,而对 父bash 没有影响
##### 4. 如何处理内置命令这种问题?
不准 父bash 创建子进程处理这个内置命令, 父bash 自己处理
方式一:
用 . 修饰脚本
方式二:
用 source 修饰脚本
方式一:

方式二:

#### 赋值和命名规则
---
##### 1. 赋值和命名规则
变量名命名的规则 :
-
首个字符必须为字母(a-z 或者 A-Z)
-
中间不能有空格,可以使用下划线()
-
不能使用标点符号
-
不能使用bash中的关键字(可以通过help命令来查看关键字)
##### 2. 使用一个赋过值的变量,给变量前加 $ :

vim test2.sh:
#!/bin/bash
myint=22 mychar=c myfloat=3.15 mystring="hello Shell"
echo mychar echo mystring

而如果要实现赋过值的变量和一个字符串拼接,应该在变量名外面加上{ },为了让解释器更好的识别变量边界:

由上图我们可以看出:
-
实现两个赋过值的变量拼接: b 直接将两个变量拼接在一起
-
实现一个赋过值的变量和字符串拼接:
给变量外边加上花括号{};用来区分边界
-
如果不加花括号,则会将变量和紧挨着的字符串一起当做一个新的变量 这样输出的结果就为空

##### 3. 只读变量 & 删除变量
---
###### 只读变量:使用readonly修饰变量
#!/bin/bash
readonly mystr="hello" echo mystr

###### 删除变量:使用unset命令

而只读变量是不能被删除的!

##### 4. 变量类型 :
---
Shell变量是弱类型,而这里的变量类型和C语言的变量类型是不一样的
-
本地变量
简单的来说:本地变量就好比是C语言中的局部变量
只在当前的Shell实例中有效,其他的程序无效 -
环境变量
类似于C语言中的全局变量 在所有的程序中都有效 命令:export 环境变量
-
Shell变量
意思就是Shell脚本中的变量 有两种 :本地变量 环境变量
下面通过例子来证明:

##### 5. 获取字符串的长度 & 提取子字符串 :

#!/bin/bash
mystring=abcde12345
echo ${#mystring} # 获取字符串的长度
echo {mystring:1:4} # 从字符串第2个字符开始截取4个字符 echo {mystring:2:5} # 从字符串第3个字符开始截取5个字符 [root@localhost Shell]# bash test5.sh 10 bcde cde12
-
${#变量名} : 表示获取变量的字符串长度
-
{mystring:1:4}: 表示从某个字符开始(下标)截取5个或者4个字符
(后面的表示字符的个数而不是结束位置的下标)
##### 6. 通配符 :
-
- :匹配0个或多个任意字符
- ? : 匹配一个任意字符
- :匹配一个方括号中的任意一个字符的一次出现
下面通过实例来解释上的意思:
##### 1. \*

##### 2. [ ]

##### 3. ?

##### 4. [ ]?

##### 5. 删除所有带file的文件:

#### 命令代换和算术代换
---
##### 1. 命令代换 :
两种方式:
1. 用反引号``将命令括起来
注意:内容其实也是一条命令
``反引号不要写成单引号
2. 用$()将命令括起来
Shell先执行该条命令,再去将输出结果立刻代换到当前的命令行中
代码解释:


##### 2. 算术运算:
常用的算术运算符: (()) 双括号
而这个只能用做+-*/% <<和()的运算符,并且只能进行整数运算
代码解释:


错误:

#### 转义字符
---
和C语言相似,将\当做转义字符(\还可以被当成续行)
另外:如果文件名带有-(横杠)的话,用上面的转义字符 \ 是不行的
两种方式解决:
1. touch -- -file1
2. touch -- ./-file.bck
#### 单引号和双引号的区别
---
C语言中:
1. 单引号 '':用来界定字符的
2. 双引号 "":用来界定字符串的
而Shell中,两者都是用来界定字符串的界定符
两者的区别就是:
1. 单引号 '':将单引号的字符串按照原样输出,不做任何转换
2. 双引号 "": 会将字符串中的转义字符·反引号都会被当做命令执行
下面通过例子来解释:
#!/bin/bash