shell 编程
内置变量使用方法
echo "#当前shell脚本的文件名: $0"
echo "#第1个shell脚本位置参数:$1"
echo "#第2个shell脚本位置参数:$2"
echo "#第3个shell脚本位置参数:$3"
echo "#所有传递的位置参数是: $*"
echo "#所有传递的位置参数是: $@"
echo "#总共传递的参数个数是: $#"
echo "#当前程序运行的 PID 是: $$"
echo "#上一个命令执行的返回结果: $?"
shell变量替换语法
变量语法 | 解释 |
---|---|
${#变量} | 获取变量值的长度 |
${变量#匹配规则} | 从头开始匹配,最短删除 |
${变量##匹配规则} | 从头开始匹配,最长删除 |
${变量%匹配规则} | 从尾开始匹配,最短删除 |
${变量%%匹配规则} | 从尾开始匹配,最长删除 |
${变量/旧字符串/新字符串} | 替换变量内的旧字符串为新字符串,只替换第一个 |
${变量//旧字符串/新字符串} | 替换变量内的旧字符串为新字符串,全部替换 |
${变量:匹配规则:匹配规则} | 索引及切片 |
判断条件
最基础的判断标志
-eq | == |
---|---|
-ne | != |
-gt | > |
-ge | >= |
-lt | < |
-le | <= |
测试不同输出的返回值
= 结论 虽然不同的命令的输出结果都可能是空,但是他们的执行结果的返回值不同, | 返回值是 if判断的 唯一标准 而非输出结果 =
if 比较 文件/目录 所使用的参数
选项 | 说明 | 示例 |
---|---|---|
-e | 如果文件或目录 存在 则为 真 | [ -e $filename] |
-s | 如果 文件存在且至少有 一个字符则为真 | [ -s $filename] |
-d | 如果 是目录 则为真 | [ -d $dirname] |
-f | 如果是普通文件 则为真 | [ -f $filename] |
-n string | 如果string为空 则为真 | [ -n "$string"] |
-z | 如果文件为空 则为真 | [ -z $filename] |
-r -w -x | 如果文件 可读/可写/可执行 则为真 | [-r/-w/-x $filename] |
getopts -参数 && 备份数据库 例子
感觉 | 挺难的
真的 || 挺难的
(),(()) ,[], [[]] ,{},的作用和区别
`() | 单小括号
功能 | 解释 | |
---|---|---|
1.命令组 | `括号中的shell 会新开一个子shell顺序执行, <br /> | 所以括号中的变量不能够被脚本余下的部分使用;`<br />括号中多个命令会用分号(;)隔开最后一个命令可以没有分号,<br />各命令和括号中间不必有空格 |
2.命令替换 | 等同于cmd ,shell 扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次 <br />得到其标准输出,再将此输出放到原来的命令,等同于 反引号(``)<br />有些shell不支持 如 tcsh |
|
3 初始化数组 | 用于初始化数组 如 array(a b c d)
|
(()) | 双小括号
功能 | 解释 | |
---|---|---|
1.计算 | `这种扩展计算时整数型的计算, | 不支持浮点型.` <br />表达式 $((exp)) 其中 exp只要符合 C语言的规则的运算符即可<br />包括 += -= <= >= <br />进行不同进制转换到10进制运算 |
2 重定义变量值 | `在 ((exp)) 中可以对变量进行重新定义或者重新赋值,<br /> | 且之后的脚本全部有效 (不像是() 那样只在子进程中有效 )` |
3 算数比较 | 在 ((exp)) 中可以进行算数比较 (不能进行字符串比较 ), <br />(())中的变量可以省略 $ 符号的前缀,也可以带着 |
[图片上传失败...(image-145767-1573700063042)]
[] | 单方括号
功能 | 解释 |
---|---|
1.条件判断 | [] 本质上是 test 语句 [ 调用了 test的命令标识,]是关闭条件判断 |
2.字符范围 | 用作正则表达式的一部分,描述一个匹配范围,入删除一个字符串中所有的数字 |
3.数组的下标 | 在一个array之后 ,作为引用数组元素的下标 |
[[]] | 双方括号
双方括号[[]] 也是条件判断结构,与 [] 有以下区别:
-
条件判断
本质上,
[]和test 是命令 | 而 [[]]是关键字,所以重定向等字符在[]中会被认为是重定向,而在[[]]中是比较符号的意思
-
``双方括号可以使用 | &&,||,< >操作符,但是出现在[]中就会报错,`
if [[ $a != 1 && $a != 2 ]] #如果是[]就会报错 if[ $a != 1 ] && [ $a != 2] #或者 if [ $a !=1 -a $a != 2 ]
-
[[]]支持字符串的匹配,[]不支持, 使用 = 或者== 比较
等号右边可以是一个模式,例如
[[ "hello" == hell?]], | 但是右边不可以加双引号(""),否则会当成一个固定的字符串
例如
[[ "hello" == "hell?"]] | 为假
[[]] 支持算数扩展,而[]不支持,例如 | if [[ 1+2 -eq 3 ]]
但是 if [ 1+2 -eq 3 ] 则会报错返回状态码,
本质上,bash把[[]]中的表达式看作一个单独的元素,并返回一个退出状态码。
{} | 大括号
{}可以作为通配符进行扩展,有两种用法:
echo {a,b}.txt 输出a.txt b.txt。与echo [a-b].txt区别在于,后者只输出存在的文件名,
而前者不管是不是存在此文件,永远都会输出a.txt b.txt,
因为{}的字符扩展和是不是文件名没有关系。echo {a..c}.txt输出a.txt b.txt c.txt。
这两种扩展也可以用于循环
{} 代码块
又被称为内部组,格式为`{ cmd1;cmd2;}`,这个结构事实上创建了一个匿名函数 。
{}与()都可以执行一连串命令,区别如下:
()会新开一个子进程,括号内命令与括号外无关。{}内的命令不会新开一个子进程运行,即脚本余下部分仍可使用括号内变量。
两者括号内的命令间都要用;隔开,但()最后一个命令的分号可有可无,但{}最后一个也必须有分号。
{}的第一个命令和左括号{之间必须要有一个空格(右括号}无此要求),而()两个括号的空格均可有可无。
特殊替换结构
有4种替换结构 | ${var:-string},${var:+string},${var:=string},${var:?string}
${var:-string}
表示 若变量 var !=空 则等于var的值, 为空则等于 string 的值${var:=string}
的赋值规则与${var:-string} 类似,但多了一步: || 若var为空时,会对var赋值string(var=string)
${var:+string} || 如果var 为空, 则为空,如果var 不为空 ,则为 string值
-
${var:?string}
若变量var不为空.则=var的值,如果为空 ,则会把string输出到标准错误输出中, || 并从脚本中退出
我们可以利用此特性来检查是否设置了变量的值
例子 演示
{}变量替换规则
变量语法 | 解释 | |
---|---|---|
${#变量} | 获取变量值的长度 | |
${变量#匹配规则} | 从头开始匹配,最短删除(非贪婪) | |
${变量##匹配规则} | 从头开始匹配,最长删除(贪婪) | |
${变量%匹配规则} | 从尾开始匹配,最短删除(非贪婪) | |
${变量%%匹配规则} | 从尾开始匹配,最长删除(贪婪) | |
${变量/旧字符串/新字符串} | 替换变量内的旧字符串为新字符串,只替换第一个 | |
${变量//旧字符串/新字符串} | 替换变量内的旧字符串为新字符串,全部替换 | |
${STR/#SUBSTR/REPLACE} | STR开头的,则用SUBSTR | |
${STR/%SUBSTR/REPLACE} | STR结尾的,则用SUBSTR | |
${VAR:?MSG} | VAR未定义或者为空则打印$MSG | |
${变量:匹配规则:匹配规则} | 索引及切片 | |
${! 变量} | 变量的间接引用 `a=b;b=12345;echo ${! a} | 结果为12345 而非 b` |
${string^^} | 小写字母转大写(string前面没有$) | |
${string,,} | 大写字母转小写(string前面没有$) | |