set 的二三事

在任何 shell 教程中,set 命令总是被简单的放在 "变量" 一节中简单提及,然后就消失无踪. 对于一个属于 find, tar 这样复杂强大的命令来说, 这无疑是焚琴煮鹤。再考虑到它对我们编写 shell 脚本所能作出的贡献,损失就更大了.

因此,set 值得花一篇文章的功夫详细讲述.

所有人都知道的基本应用

最简单的,set 会显示你的所有变量.

set 参数 则会把 参数 传给该 shell 实例的位置参数,并清空以前存在的所有位置参数.

shell 更像编程语言 -- set 的一些选项

括号后面的为对应的选项名.

  • -u: 当引用未定义的变量时,shell 报错并退出.(nounset)
  • -e: 当引用不存在的命令时,shell 报错并退出.(errexit) 当然, 要是存在管道的话,只有最后一个命令失败才会退出。因此我们有 pipefail 选项
  • -C: 当重定向命令要覆盖已存在的文件时,shell 报错且文件不会被覆盖.(noclobber)
  • -x: 将正在执行的语句输出到标准错误流中.(xtrace). P.S.: 如果想要临时取消这个选项,可以用命令 || true.

其他的奇怪选项

  • -v: 将 shell 的输入输出到标准错误流中.
  • -f: 禁止路径扩展.(noglob)
  • -n: 试运行命令。交互式 shell 下无效.(noexec)
  • -a: 所有变量定义都必须为全局.(allexport)
  • -o 设置名:打开对应设置。某些没有对应选项的设置:
    • pipefail: 上文已经提到过了,当管道中任何一个命令执行失败时, 整个语句执行失败.
    • nolog: 禁止往历史写函数定义.
    • vi: 用 vi 模式编辑命令.
    • ignoreeof: 禁止 <C-d> 退出登录.

支持 * UPU* 的 shell 选项,比较复杂,目前尚未理解

  • -b: (notify)
  • -h:
  • -m: (monitor)

最后

要想取消某个设置,只要把对应的 "-" 改成 "+" 就行.