010_shell编程 - llj2kh/studynote GitHub Wiki
shell 编程
1 注意事项
- 赋值时“=”两边不能有空格,否则就是语法错误了。
- Bash变量命名只能使用字母,下划线和数字,并且不能以数字开头。
- 变量的引用有两种形式:
- $var
- ${var}
- ' ' :单引号里的任何字符都会原样输出,单引号中对变量引用是无效的,且单引号中不能出现单引号(对单引号使用转义符也不行)
- " ":双引号里可以引用变量,可以出现转义字符。
- 使用 readonly 命令可以将变量限定为只读变量
- 使用 unset 命令可以删除变量,但是不能删除只读变量。
- Bash变量都是字符串。但是依赖于上下文,Bash也允许比较操作和算术操作。决定这些的关键因素是变量中的值是否只有数字,只有当变量是纯数字时,该变量才是“数字类型的”,否则就是字符串类型的。
- Bash中的数字默认的是十进制,八进制需要以0开头,十六进制以0x开头。
- 空变量+数字:数字变量
- 未定义的变量+数字:数字变量
- 局部变量(local variables):这种变量只有在变量所在的代码块或者函数中才可见,需要使用local声明;
- 全局变量:Bash中用户自定义的普通变量默认是全局变量,可以在本文件中的其它位置引用;
- 环境变量(environmental variables):所有的程序(包括shell启动的程序)都能访问环境变量。如果一个shell脚本设置了环境变量,需要用 export 命令来通知脚本的环境。
2 Bash的传参机制
shell通过位置参数(positional parameters)来给脚本文件传递参数,就是从命令行中传进来的参数,$0, $1, $2, $3... 其中:
- $0 是该脚本文件的名字
- $1 是第一个参数, $2 是第 2 个参数...
- $9 以后就需要大括号了,如 ${10}, ${11}, ${12}...
- $* 与 $@ 区别:
- 相同点:都表示引用所有的位置参数;
- 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$- 显示Shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
3 Bash函数
- 关键字function是可选的;
- 函数定义必须在第一次调用前完成;
- 在一个函数内嵌套另一个函数也是可以的,但是不常用.
- 函数以位置来引用传递过来的参数(就好像他们是位置参数一样), 例如$1, $2, ...
- 在函数调用之前,所有在函数内声明且没有明确声明为 local 的变量都可在函数体外可见(默认为全局变量)。
- 如果变量用local 来声明,那么它只能在该变量声明的代码块中可见。这个代码块就是局部"范围"。在一个函数内,局部变量意味着只能在函数代码块内它才有意义。
4 Bash数组
- Bash 只支持一维数组,用圆括号()来表示,数组元素之间用"空格"符号来分割
- 初始化时不需要指定数组的大小。bash数组元素的下标从0开始。
- 数组成员不必一定要连续,空缺元素是允许的;
- 数组的一部分成员允许不被初始化, 没有被初始化的元素将打印空(NULL)值;
- 访问数组元素的一般格式:
- ${var[3]}
- 遍历数组
- 使用* 或@ 可以获取数组中的所有元素
- ${var[*]}
- 获取数组长度
- ${#var[*]}
5 Bash字符串操作
-
${string/#/abc}
在字符串前面添加abc
-
${string/%/bac}
在字符串后面添加abc
- ${!var[*]}
获取数组的索引列表 - 获取字符串长度
- ${#var}
- bash允许直接将字符串拼接在一起以获得新的字符串。
- "#"表示从头匹配,%表示从尾匹配
- 一个符号(#或者%)表示最短匹配,两个符号(##或者%%)表示最长匹配
${string:position} 在string中, 从位置position开始提取子串
${string:position:length} 在string中, 从位置position开始提取长度为length的子串
${string#substring} 从string的开头, 删除最短匹配substring的子串
${string##substring} 从string的开头, 删除最长匹配substring的子串
${string%substring} 从string的结尾, 删除最短匹配substring的子串
${string%%substring} 从string的结尾, 删除最长匹配substring的子串
${string/substring/replacement} 使用$replacement 来代替第一个匹配的$substring
${string//substring/replacement} 使用$replacement 代替所有匹配的$substring
${string/#substring/replacement} 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
${string/%substring/replacement} 如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring