Kaede Akatsuki

中二病也要开发 Android

Bash 编程 - 从入门到入土

Bash,面向 Google 编程!

Bash,一门典型的面向 Google 编程的语言(类似的还有面向 StackOverflow 编程的 vim),最大的语言特性是其“不确定性原理”(你要么学会了 Bash 了语法,要么写出了能正常运行的 Bash 脚本,但是不能即学会了语法又写出了脚本),你今天刚学会的语法,到了明天就不一定会记得了;今天刚写好的代码,到了明天就不一定能运行了。与其回忆昨天学了什么,还不如直接问 Google。

Bash 学习的深入可真是“从入门到入土”,个人感觉最佳实践应该是把 Bash 作为脚本入口,包一层别的脚本语言(比如 Python),后续工作全交由后者处理。

Bash is Untype

  1. Bash 没有类型,所以 Bash 所有类型、对象、变量都是 Text/String 文本,没有结构体(或者说唯一的结构体就是空格分隔的文本)。
  2. if [ $bool ] 其实是判断变量 bool 是不是 Not Empty。
  3. 因为都是文本类型,所以判断 Number 变量大小、加减,都需要使用配套的命令:-eq/-ne/-gt/-lt。

面向文本编程

  1. Bash 语言里,一切都是 Text。
  2. Bash 没有类型,甚至没有动态语言特有的结构,纯靠 Shell 工具解析 Bash 文本并执行相关指令。文本约束性太弱,经常会有意想不到的“惊喜”。
  3. 处理带有空格的 Var 的时候比较危险,因为空格有可能被当成 Bash 指令分隔符处理。
  4. sh <bash_file> 或者 eval 的时候,args 是被当成一个文本在解析成入参的。如果 args 包含有 Empty 参数,则该解析后的入参里会漏掉该参数并导致参数位置出现偏移。
  5. 文本有些场景需要加转义字符但是经常完了但是确没报错,比如:比较大于操作符 › 被当成文本输出操作符执行且返回 true。
  6. 文本还容易被当成命令执行。
  7. 抽取 Bash 重复代码段,使用 function 代替也会出现惊喜,特别是方法体里有 loop 以及需要返回值的时候。
  8. function 方法块内最后的 statement 如果没有作为返回值赋值给一个 var,或者在方法最后使用 echo 来消费,则调用方法后改 statement 的值会作为 bash 指令执行。

Bash 编程最佳实践

  1. 别思考 Bash 语法,直接 Google 反而更快一些。
  2. Bash 语法有比较严重的兼容性问题,不仅不同 Bash 版本之间的 Bash 脚本表现可能不同,在不同终端(Shell)上面的运行效果可能也不一样。
  3. 要复用 Bash 代码能难,最好的实践就是 CAP 编程原则。
  4. 把 Bash 作为脚本入口,包一层别的脚本语言(比如 Python),后续工作全交由后者处理。