Bash浅谈
一、Bash简介
1.What’s Bash
- Bash 是 Unix 系统和 Linux 系统的一种 Shell(命令行环境),是目前绝大多数 Linux 发行版的默认 Shell。
- that’s all.
二、脚本常识
1.声明Bash Shell
#!/bin/bash
:声明使用的解析器,可避免系统采用默认解析器去运行脚本带来的可能的错误。Attention:
①第一行的“井号+感叹号+脚本解释器程序路径”,说明这是一个可执行的脚本;
②任意行的单独的”井号“都是注释作用,非第一行的“井号+感叹号“也是注释作用;
③避免问题:你的脚本是Bash Shell,系统默认的是Csh,若不声明,那么你的脚本运行错误;
2.脚本的执行权限
- Linux脚本 不以 后缀来判断它是否可执行,而是以命令 ”ls -l“ 来查看它是否是可执行文件,可使用chmod来变更脚本权限(该命令使用方式请自查文档),这样才能运行;
3.脚本的组织方式
- 脚本是由命令组成的,而命令的执行都是单独的,即使报错也不影响下一条命令的执行;一行语句可以包含多个命令,用”;”隔开。
三、命令基础理解
1.echo命令
echo "xxx" "xxx" …… "xxx"
ORecho xxx …… xxx
:单行输出;echo "xxx"
:xxx
为多行文本时可以一次输出多行;echo -n "xxx";echo "yyy"
:可以实现输出xxxyyy
,即-n
可以省略换行符;- echo -e “damn\nbro”:若没有参数
-e
,则转义换行字符\n
不会翻译;
2.命令的继发关系
command1 ;command2
:无论命令1是否成功执行,都会继续执行命令2;command1 && command2
:只有命令1成功执行,命令2才会执行;command1 || command2
:只有命令1执行失败,命令2才会执行;
3.type命令
type command
:查看command
是内部命令还是外部程序;type -a command
:显示command
的所有定义;type -t command
:返回command
的类型:别名(alias
),关键词(keyword
),函数(function
),内置命令(builtin
)和文件(file
);
四、命令的模式拓展(通配符拓展)
1.~拓展
~
会自动拓展成当前用户的主目录;~+
会自动拓展当前所在目录;
2.?拓展
?
字符代表当前目录(不包括子目录)下里面的任意单个字符,不包括空字符;?
字符扩展属于文件名扩展,只有文件确实存在的前提下,才会发生扩展。如果文件不存在,扩展就不会发生。
3.拓展*
*
字符代表当前目录(不包括子目录)下文件路径里面的任意数量的任意字符,包括空字符。- 如果要匹配隐藏文件,需要写成
.*
,否则不会匹配; *
字符扩展属于文件名扩展,只有文件确实存在的前提下才会扩展。如果文件不存在,就会原样输出。
4.[ ]拓展
[xyz]
代表当前目录(不包括子目录)下文件路径里面的xyz
中的任意一个字符。[^xyz]或者[!xyz]
代表当前目录(不包括子目录)下文件路径里面的除了xyz
以外的任意一个字符。[a-c]
等同于[abc]
,[!a-c]
等同于[!abc]
;- [ ]扩展扩展属于文件名扩展,只有文件确实存在的前提下才会扩展。如果文件不存在,就会原样输出。
5.{ }拓展
- 大括号扩展
{1,2,3}
表示分别扩展成大括号里面的所有值,各个值之间使用逗号分隔; - 大括号拓展可以嵌套,也可以与其他模式联用,并且总是先于其他模式进行扩展;
{1..4}
等同于{1,2,3,4}
,{4..1}
等同于{4,3,2,1}
,{01..4}
等同于{01,02,03,04}
,{0..8..2}
等同于{0,2,4,6,8}
;- 大括号扩展不是文件名扩展。它会扩展成所有给定的值,而不管是否有对应的文件存在。当对应文件不存在时,相应命令会报错或者继续通配输出;
6.变量拓展
- 将美元符号
$
开头的词元视为变量,将其扩展成变量值; - 变量名除了放在美元符号后面,也可以放在
${}
里面; ${!string*}
或${!string@}
返回所有匹配给定字符串string
的变量名;
7.子命令拓展
$(command)
可以扩展成另一个命令的运行结果,该命令command
的所有输出都会作为返回值。
8.算术拓展
$((...))
可以扩展成整数运算的结果:echo $((2 + 2))
输出4
;
9.字符类拓展
[[:class:]]
表示一个字符类,扩展成某一类特定字符之中的一个;- 常见的字符类如下:
[[:alnum:]]
:匹配任意英文字母与数字;[[:alpha:]]
:匹配任意英文字母;[[:graph:]]
:A-Z、a-z、0-9 和标点符号;[[:lower:]]
:匹配任意小写字母 a-z;[[:upper:]]
:匹配任意大写字母 A-Z;[[:print:]]
:ASCII 码 32-127 的可打印字符;[[:cntrl:]]
:ASCII 码 0-31 的不可打印字符;[[:digit:]]
:匹配任意数字 0-9;[[:xdigit:]]
:16进制字符(A-F、a-f、0-9);
- 字符类的第一个方括号后面,可以加上感叹号
!
(或^
),表示否定。比如,[![:digit:]]
(或[^[:digit:]]
)匹配所有非数字。 - 字符类也属于文件名扩展,如果没有匹配的文件名,字符类就会原样输出。
10.Cautions
- 通配符是先解释再执行;
- 所有文件名扩展只匹配单层路径,不能跨目录匹配,即无法匹配子目录里面的文件。或者说,
?
或*
这样的通配符,不能匹配路径分隔符(/
); - Bash 允许文件名使用通配符,即文件名包括特殊字符。这时引用文件名,需要把文件名放在单引号或双引号里面。
五、变量
1.创建变量
- 命令格式:
xxx=value
;Attention:
①由字母、数字和下划线组成;
②不能以数字开头;
③赋值时等号两边不能有空格;
④变量的值包含空格则需放入引号中;
⑤Bash没有数据类型的概念,所有变量值都是字符串;
2.读取变量
常用命令格式:
$A或者${A}
;Attention:
①当变量不存在时,不会报错,而是会输出空字符;
②后者比前者用途更广,比如当变量名与其他字符连用时:${A}damn
会输出M3damn
,而#Adamn
会去尝试读取变量Adamn
而输出空字符(A=M3);特殊命令格式:
${!A}
可以输出变量的最终值M3
(A=DAMN;DAMN=M3
);"${A}"
可以完整地输出变量值中的所有空格:echo ${A}
会输出1 2 3
;echo "${A}"
会输出1 2 3
(A="1 2 3"
);
3.删除变量
- 命令格式:
unset A
A=''
A=
Attention:因为不存在的 Bash 变量一律等于空字符串,所以即使
unset
命令删除了变量,还是可以读取这个变量,值为空字符串。所以,删除一个变量,也可以将这个变量设成空字符串。
4.变量继承
- 命令格式:
export A=damn
;Attention:上面命令执行后,当前
shell
和随后新建的shell
都可以读取变量A
,并且子shell
修改的变量不会影响父shell
;
5.特殊变量
$?
:$?
为上一个命令的退出码,用来判断上一个命令是否执行成功。返回值是0
,表示上一个命令执行成功;如果不是零,表示上一个命令执行失败;- $$$$:$$$$为当前 Shell 的进程 ID;
$_
:$_
为上一个命令的最后一个参数;$!
:$!
为最近一个后台执行的异步命令的进程 ID;$0
:$0
为当前 Shell 的名称(在命令行直接执行时)或者脚本名(在脚本中执行时);$-
:$-
为当前 Shell 的启动参数;
6.变量的默认值
${A:-damn}
:如果变量A
存在且不为空,则返回它的值,否则返回damn
。它的目的是返回一个默认值;${A:=damn}
:如果变量A
存在且不为空,则返回它的值,否则将它设为damn
,并且返回damn
。它的目的是设置变量的默认值;${A:+damn}
:如果变量A
存在且不为空,则返回damn
,否则返回空值。它的目的是测试变量是否存在;${A:?damn}
:如果变量A
存在且不为空,则返回它的值,否则打印出A: damn
,并中断脚本的执行。如果省略了damn
,则输出默认的信息“parameter null or not set.”。它的目的是防止变量未定义;- 上面四种语法如果用在脚本中,变量名的部分可以用数字
1
到9
,表示脚本的参数。
7.declare命令
- 语法格式:
declare -option A=value
:declare
命令可以声明一些特殊类型的变量,为变量设置一些限制,比如声明只读类型的变量和整数类型的变量。 declare
命令如果用在函数中,声明的变量只在函数内部有效,等同于local
命令;- 不带任何参数时,
declare
命令输出当前环境的所有变量,包括函数在内,等同于不带有任何参数的set
命令。-i
:-i
参数声明整数变量以后,可以直接进行数学运算;-x
:-x
参数等同于export
命令,可以输出一个变量为子 Shell 的环境变量;-r
:-r
参数可以声明只读变量,无法改变变量值,也不能unset
变量;-u
:-u
参数声明变量为大写字母,可以自动把变量值转成大写字母;-l
:-l
参数声明变量为小写字母,可以自动把变量值转成小写字母;-p
:-p
参数输出变量信息;-f
:-f
参数输出当前环境的所有函数,包括它的定义;-F
:-F
参数输出当前环境的所有函数名,不包含函数定义;
8.readonly命令
readonly
命令等同于declare -r
,用来声明只读变量,不能改变变量值,也不能unset
变量;
9.let命令
let
命令声明变量时,可以直接执行算术表达式;let
命令的参数表达式如果包含空格,就需要使用引号;let
可以同时对多个变量赋值,赋值表达式之间使用空格分隔;
六、字符串操作
1.字符串的长度
- `$