Bash简单小结
简单介绍 && 为什么要写 Bash
bash 是一个用户态人机接口
使用理由
- 工作需要没得选, 比如嵌入式裁剪的 rtos 只能提供一个简单的 posix 兼容的原版 sh
- 相较于 python 等重量级选手, bash 轻便快速, 与 Linux 下的各种基础命令交互也简单 (反正都是字符串)
基础知识
shebang
shebang 就是文件开头的 #! 开头, 用来提示文件应该用哪个解释器 (interpreter)
|
|
听起来很简单…但是
为啥很多时候会我们觉得 bash 很恶心, 因为他的确讲究很多
假设你运行一个脚本 bash test.sh, test.sh 的内容是就是上面这段内容, 那么脚本到底用 bash, 还是 sh 呢? 可以用 这个命令验证 cat /proc/$$/cmdline
写 shebang 也有个小 trick, 尽量写成 /usr/bin/env bash, 因为 /bin/bash 不一定存在
setopt
这些东西很常见, 但是第一次遇见一定是不知所云的, 稍微 google 一下就知道这些标志的意思了
|
|
常见的就这几个, 遇到不懂的也可以当场 google, 不丢人哈
字符串
bash 中是没有类型系统的, 默认所有的变量都是字符串, 下面说一些小知识
- 大部分特殊字符比如
.+*?这种符号在引号中是没有特殊含义的, 但是双引号中\`$这三个字符是会被转义的, 单引号中众生平等没有任何转义 echo中-e选项是 respect 转义字符,-n选项是取消默认的换行符, 不区分单双引号
常见的特殊符号
|
|
数字
上文说到 bash 中没有变量系统, 所有内容都是字符串, 那我要算术运算的时候咋办呢 比如
|
|
下面是几种正确使用方法
declare -i var上面这个表达式会把 var 声明为一个整数类型, 这样之后, 写var=$var+1, 是改变不了var的内容的, 但是要注意即使这样也达不到想要的效果- `expr $var+1
var=$(($var+2))
条件表达式
bash 中常见判断的就 if 和 case, 这里只介绍下 if 模板如下:
|
|
这里的 elif 和 else 可以省略, expression 有一些常见形式, 举例如下
|
|
[ ] 和 [[ ]] 的区别
很多地方都会说, 尽量用 [[ ]] 而不要用 [ ], 为什么呢
单中括号 [ ] 的类型是 builtin, 存在于/bin 目录下, 等于 test, 其参数会被 shell 解释
双中括号 [[ ]] 是 keyword, 是 bash 的扩展, 其作为一个整体被 shell 解释
|
|
另外, [[ ]] 支持 && || 之类的表达式, 他的兄弟并不支持
循环和数组
网上抄了几个例子, 自行感受吧
|
|
函数和 source
同上, 抄了几个例子
|
|
这里写的是 bash 的基础中的基础, bash 中的 tricks 也有很多, 见参考文档 1, 数量很吓人
一些 Bash 中比较容易犯的错误
[ ]和两侧的括号忘记写- windows 下面写的脚本放到 linux 中执行, 忘记用 dos2unix
中的值没有正确使用双引号, 这会导致模式匹配而非字符串匹配- 用
(( ))来做算术运算而非 - 在同一个管道中同时读写
cat file | sed s/foo/bar/ > file
总之, 要认识到 bash 中很多地方会用 $IFS (默认空格) 做分隔符, 这会导致异常行为, 要避免这种情况, 需要你正确地使用双引号, 很多细节可以见参考文档 2
posix shell 和 bash 区别
posix shell 这位爷更是重量级, 他是各类衍生 shell 的老祖宗, 所以很多 bash 特有的语法他是不认的, 大概正常人都巴不得脚本都用 python 写来减少心智负担, 没办法, 不得不用的时候终究是逃不掉的
内容自己写好累, 参考下 chromium 的 coding style 的内容吧
- Tests using the double-bracket test operator, e.g.
"${SOMEVAR}" == "test value" - Arrays, e.g.
foo=( 1 2 3 ) - The
declarebuilt-in command - Using the
functionkeyword to define a shell function (you should never use this though, even with bash) - Brace expansion, e.g.
echo {a,b}{c,d}
what happens when open a shell
用户登录
登录 Session 一般进行整个系统环境的初始化, 启动的初始化脚本依次如下.
/etc/profile:所有用户的全局配置脚本./etc/profile.d目录里面所有.sh文件~/.bash_profile:用户的个人配置脚本.如果该脚本存在, 则执行完就不再往下执行.~/.bash_login:如果~/.bash_profile没找到, 则尝试执行这个脚本(C shell 的初始化脚本).如果该脚本存在, 则执行完就不再往下执行.~/.profile:如果~/.bash_profile和~/.bash_login都没找到, 则尝试读取这个脚本(Bourne shell 和 Korn shell 的初始化脚本).
非登录, 比如手敲一个 bash 命令
- /etc/bash.bashrc
- ~/.bashrc
一些常见的技巧
在 bash 中 trap 各类信号来做 cleanup
TODO
和 rg/fd/sed/awk 等协同使用
TODO