bash test 备忘
一直以来都很抗拒写shell脚本。从编程语言的角度评价,所有的shell都是相当糟糕的语言,到处都充满了混乱、丑陋和怪癖。我坚持认为,只要有可能,系统脚本就应该用一种成熟的、严肃的语言来写——至少是像Python这样的语言。然而,有时候,却不得不用shell编程。比如,当你给一台路由器编程的时候,它的存储空间可能不足以安装任何一门严肃的语言,shell就成了唯一的选择。因为不想付出记忆负担,而语言又缺乏一致性无法“凭直觉”去尝试,为了避免每次写shell脚本都要为了查一些基本操作而满世界google,还是在这里记录一些东西吧,找起来方便。
在shell中,测试是一个物理上存在于磁盘上的“命令”而不是“运算符”,而且有太多种:test
, [
, [[
, 我实在不想去深究它们有什么区别,搞清楚这些东西就如同去翻历史的裹脚布。
这里大概记录测试的类型:
逻辑运算
-a # 逻辑 and, 类似于 &&
-o # 逻辑 or, 类似于 ||
! # 逻辑 not
整数比较
-eq # 相等
-ne # 不相等
-gt # 大于
-ge # 大于等于
-lt # 小于
-le # 小于等于
# 由于上面的比较运算太过于反人类,于是又发明了双括号。双括号里面可以用正常人类可读的代码
(("$a" < "$b"))
(("$a" >= "$b"))
字符串比较
= # 比较字符串是否相等
== # 另一种相等测试,在单括号 [ ] 和双括号 [[ ]] 中有不同的行为
!= # 不相等
< # 小于(比较 ascii 码)
> # 有没有人给我解释一下,为什么比较字符串可以用 >, <, 而比较数字要用 -lt, -gt?
-z # 空字符串测试
-n # 非空字符串测试
文件测试
-e # 文件存在
-f # 文件是普通文件(不是目录或设备)
-d # 文件是一个目录
-h # 文件是符号链接
-L # 和上面一样
-b # 文件是块设备
-c # 文件是字符设备
-p # 文件是一个管道
-S # 文件是一个 socket
-s # 文件非零
-t # 测试给定的文件描述符是否与终端设备相关联
# 可用于检查脚本中的 stdin 或 stdout 是否为终端 [ -t 0 ], [ -t 1 ]
-r # 文件有读权限
-w # 文件有写权限
-x # 文件有可执行权限
-g # set-group-id (sgid) flag set on file or directory
-u # set-user-id (suid) flag set on file
-k # sticky bit set
-O # 你是文件的拥有者
-G # 你和文件的拥有者同组
-N # 文件在最后一次读取后被修改过
-nt # [ $f1 -nt $f2 ] 前面的文件更新
-ot # [ $f1 -ot $f2 ] 前面的文件更旧
-ef # [ $f1 -ef $f2 ] 两个文件硬链接到相同的文件