记录点shell的一些基本语法规则,后续可以慢慢补充
- #!规定可执行文件路径,记得chmod修改权限
- 定义变量,具体看firstshell.sh文件里面的内容,使用时在前面加$符号,最好在每次使用变量的时候添加大阔号起到分割符的作用。
- 变量可以重新赋值,赋值无需添加dollor符号
- 可以使用readonly符号修饰变量,再次赋值的时候脚本会抛错
- unset可以删除变量,使得变量内容为空,但是unset不能删除只读变量
插入两条vim的笔记:
跳转到文件开头:gg
跳转到文件结尾:shift + g
跳转到每行开头:0
跳转到每行结尾:$
- 字符串:
- 单引号字符串中无法使用转义符和变量,但是可以通过多组成对单引号进行拼接。
- 双引号:可以使用转义字符,变量,也可以是用多对双引号进行拼接
- 总的来说还是双引号好用一点,shell中字符串的拼接直接放在后面就好了,具体看firstshell.sh
- 获取字符串长度:
echo ${#variable_name}
注意一定大括号包起来,否则dollor不会吧#和变量名算一起,变量为数组时候,等价于获取数组第一个变量的长度 - 输出子串,
echo ${variable_name:startIndex:len}
,index从0开始 - 查找字符串子串,这个指令在OS X用不了,linux GNU标准下可以正常使用。
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4, 查找i或者的位置
-
bash支持一维数组,不支持多维数组,不限制数组的大小
-
数组元素由空格来分隔,不是逗号!!!
-
数组大小没有限制,我们可以初始化长度的时候只给出3个值,但是可以操作大于等于3的index值。
-
@可以获取数组的所有元素,
echo ${my_arr[@]}
。需要注意的是,我们可以隔着复制,譬如index从0到3是有值的,4是空的,此时我们给5赋值,那么这条指令输出的内容分别是0,1,2,3,5的内容 -
# 取得数组元素的个数 length=${#array_name[@]} # 或者 length=${#array_name[*]} # 取得数组单个元素的长度 lengthn=${#array_name[n]}
注释的方式:
- 添加#号注释当前行
- 多行注释,可以使用{}括起来定义成一个函数,这样就不会执行这一段内容
- 多行注释格式
:<<EOF
...
EOF
其中:<<后面可以换成其他字符,只要结尾的时候字符是相同的即可。
- 我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推(0是脚本的文件名)
又插入几条vim的笔记
- 复制:
- yy, 复制当前行
- 3yy,复制接下来的3行
- yiw, 复制当前的word
- 剪切
- dd, 删除当前行并复制到剪切板
- 3dd, 和上面3yy类似,类推一下即可
- d$, 删除从当前指针到文件结尾的内容并复制
- 粘贴
- p从当前指针后一个位置开始粘贴
- P从当前指针前一个位置粘贴
- 一些保留变量符
参数处理 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 |
$- | 显示Shell使用的当前选项,与set命令功能相同。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
mac os上$*和$@是没有区别,linux上前者输出单字符串,后者会返回所有传递参数的序列。
其实就是字典,用法和数组基本一致。声明方式如下:
declare -A my_arr=(["google"]="www.google.com", ["runoob"]="www.runoob.com", ["taobao"]="www.taobao.com")
每个键值对用逗号分开,并且也能想数组那样无限制的赋新的键值对,获取所有元素(*或者@),获取长度(#)都和普通数组是一样的。在所有元素面前添加感叹号可以获取所有的key(和数组还是一样的,只不过普通数组的key就是下标罢了)。
- 一般借助expr和反引号实现求值
- 操作数和操作符之间需要空格,不能连在一起
- 乘号*前面要加转义字符
- 条件表达式中括号和操作数之间也要有空格,所以建议没写一个操作符或者变量都要隔一个空格。
把这个表记一下就好了,其实就是英语单词的缩写
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
equal, not equal, greater than, less than, greater than or equal, less than or equal
具体例子看relationOp.sh文件中的内容
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
记住对应关系就好了,!对应非,-o对应或(or),-a对应与运算(all)。
&&表示与,||表示或。
- 这里顺带提一下-a, -o和&&, ||的区别,前者一般在[]使用,后者可以组合command的输出结果,并且前者不支持短路,后者支持短路。
- 但是在double中括号的情况下,内部也可以使用&&和||
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否不相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n "$a" ] 返回 true。 |
$ | 检测字符串是否不为空,不为空返回 true。 | [ $a ] 返回 true。 |
这里有一点比较奇怪,==符也能作为判定两个字符串是否相等的操作符,我个人觉得用==和前面算术运算符匹配更好。
用于检测unix文件的各种属性
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
-S: 检测文件是否为socket
-L: 检测文件是否存在并且是一个符号链接。
- echo指令,没什么特殊讲的,-e选项开启转义,\n, \c这种会解析成转义字符,而不是直接输出n或者c
- printf指令,和c的printf类似,不同的是参数用空格分开,这里也不做赘述。
- test指令,其实和[ ]差不读,结合逻辑运算符的知识就能进行含义推导。
if condition1
then
command1
...
elif condition2
then
command2
...
else
command3
fi
其中elif和else都不是必须的,但是必须要有一个fi结尾。