bash编程备忘
| 1 | bash -n test.sh # 检测语法 | 
说明
若从技术的细节来看,shell会依据IFS(Internal Field Seperator) 将命令行所输入的文字拆解为”字段”(word/field)。 然后再针对特殊字符(meta)先作处理,最后重组整行命令行
- IFS:有- space或者- tab或者- Enter三者之一组成(我们常用space)
- CR: 由- Enter产生;
IFS(Internal Field Seperator)是用来拆解command line中每一个词(word)用的,因为shell command line是按词来处理的。
而CR则是用来结束command line用的,这也是为何我们敲Enter键,命令就会跑的原因。
除了常用的IFS与CR, 常用的meta还有:
| meta字符 | meta字符作用 | 
|---|---|
| = | 设定变量 | 
| $ | 作变量或运算替换(请不要与 shell prompt混淆) | 
| > | 输出重定向(重定向stdout) | 
| < | 输入重定向(重定向stdin) | 
| & | 重定向file descriptor或将命令至于后台(bg)运行 | 
| () | 将其内部的命令置于nested subshell执行,或用于运算或变量替换 | 
| {} | 将期内的命令置于non-named function中执行,或用在变量替换的界定范围 | 
| ; | 在前一个命令执行结束时,而忽略其返回值,继续执行下一个命令 | 
| && | 在前一个命令执行结束时,若返回值为true,继续执行下一个命令 | 
| ! | 执行histroy列表中的命令 | 
| … | … | 
变量
命名规则
- 等号左右两边不能使用分隔符号(IFS),也应避免使用shell的保留元字符(meta charactor)
- 变量的名称(name)不能使用$符号
- 变量的名称(name)的首字符不能是数字(number)
- 变量的名称(name)的长度不可超过256个字符
- 变量的名称(name)及变量的值的大小写是有区别的、敏感的(case sensitive,)
特殊变量
| 1 | $0 : 当前脚本的文件名 | 
$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号包含时,都以”$1” “$2” … 的形式输出所有参数,但是当它们被双引号包含时,”$*“ 会将所有的参数作为一个整体,以”$1 $2 …”的形式输出所有参数;”$@” 会将各个参数分开,以”$1” “$2” … 的形式输出所有参数
字符串操作
| 1 | ${#str} : str的长度 | 
| 1 | str='/var/log/messages' | 
变量赋值
| 1 | ${arg:-word} :假如arg为unset或者null,输出word的值但不赋值 | 
表达式
算术运算
| 1 | a=11;b=22 | 
测试表达式
test EXPRESSION[ EXPRESSION ][[ EXPRESSION ]]:推荐使用
- -eq:等于,- -ne:不等于,- -qt:大于,- -qe:大等于,- -lt:小于,- -le:小等于
- ==,- <,- >,- !=,- =~:左侧字符能否被右侧规则匹配
- -z $str: 为空则为真
- -n $str: 不空则为真
- -d file: 是否是目录
- -e file: 存在为真
- -f file: 普通文件,- -c:字符设备,- -p:管道,- -h或- -L:符号链接,- -S:套接字
- &&,- ||,- !: [ -d /aa ] && [ -f f2 ]
- -a,- -o,- !: [ -d /aa -a -f f2 ],[ ! -e /dd ]
| 1 | 
判断
- if…fi
- if…else…fi
- if…elif…else…fi
- case…esac
循环
- for
- while
- until
函数
易错
- echo
| 1 | a="this *.txt" | 
- cat
| 1 | cat <<EOF | 
- .exp1.&&.cmd1.||.cmd2.
| 1 | # 由于i++返回值为1(假),所以i--也会执行 | 
- for arg in $*
| 1 | # 正确写法 | 
- [[ -e file ]]
| 1 | 如果file是链接文件,但指向的原文件不存在时,-e的结果为1(假),如果只想判断是否存在,如下: | 
- for循环读文件不靠谱
| 1 | # 建议使用while | 
简洁
- 位置参数
| 1 | arg=${1:-123} # 当$1不存在时,arg=123 | 
- 格式化数字
| 1 | printf "%'.2f" 1234455.2323 # 1,234,455.23 | 
- here document(cat <EOF)
| 1 | while read line; do | 
- 多线程
| 1 | # 1. 使用(CMD)方式fork一个子进程来执行 | 
| 1 | # 2. 使用文件描述符及管道方式的多进程 | 
- vim编辑远程文件
| 1 | vim scp://data01.com//tmp/test.sh | 
- 编辑当前命令
| 1 | # 遇到输入比较长的命令时,需要修改时,使用 ctrl+x ctrl+e,默认使用emacs,使用vim修改~/.bashrc | 
参考
- shell 13问
- bash 编程易犯的错误