121、【OS】【Nuttx】【周边】效果呈现方案解析:find 命令格式(上)
【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
之前 blog
【OS】【Nuttx】【周边】效果呈现方案解析:通配符展开
分析了通配符展开的一个重要细节,即通配符展开是由 Shell 完成的,而不是命令,下面继续分析这条语句
local file_mtime=$(find "$dir" -name "*.html" -type f -printf '%T@' 2>/dev/null | sort -n | tail -1)
find 命令格式
首先是前面部分
find "$dir" -name "*.html"
这一小部分也有很多关键点在里面,首先来看下 find 命令的帮助文档,在 Bash 终端输入
man find
查看 find 命令的说明文档
有几个关键点:
- 首先中括号 [ ] 表示该选项可选,可以看到 find 命令的选项都是可选的,没有必选项,所以是可以单独输入 find 命令的,比如在终端直接输入 find,find 命令将打印出当前目录下的所有文件(包括子目录中的)
- 前面的可选项 [-H] [-L] [-P] [-D debugopts] [-Olevel] 用的很少,可以不关注,关键在后面两个选项 [starting-point…] [expression]
- [starting-point…]:从哪些目录开始搜索,可以是一个或多个路径(这里 … 表示该选项可以是一个或多个),如果没有设置 starting-point,那么默认当前路径 .
- [expression]:搜索条件,find 会根据表达式判断哪些文件符合要求
比如
find . -name "main*"
和
find -name "main*"
的效果是一样的
下面来分析两个容易迷惑的地方
find “./important*” 和 find ./important*
首先,该目录下有这么些子目录
如果在 Bash 终端中输入
find "./important*"
可以看到 find 命令找不到 ./important* 这个路径
因为双引号会抑制 Shell 的通配符展开(之前 blog 【OS】【Nuttx】【周边】效果呈现方案解析:通配符展开)已经分析过,此时 ./important* 将以字符串的形式作为选项 starting-point,而该路径下并没有一个叫 ./important* 的目录(这里 * 只是个普通字符)
而如果在终端中输入
find ./important*
可以看到 find 命令能够正常执行,并找出所有带 important 前缀的目录
这是因为在执行 find 命令之前,Shell 会进行通配符展开,将 ./important* 转化为 ./important_dir1 和 ./important_dir2,相当于执行命令
find ./important_dir1 ./important_dir2
终端输入上述命令
可以看到和直接输入 find ./important* 命令的效果是一样的
find -name “main*” 和 find -name main*
目录结构如下,当前目录下有如下文件
如果在终端中输入
find -name main*
可以发现报错如下
因为此时 Shell 先于 find 命令执行前,把 main* 展开成 main main.c main.s 三个文件名,相当于执行命令
find -name main main.c main.s
这个命令的前半部分
find -name main
好理解,就是找到 main 文件,但是 find 命令解析到后半部分 main.c main.s 时,由于不认识,会误认为这两个额外的东西是路径,因此报错 main.c(误认为是路径)需要再 -name 表达式之前
而如果在终端中输入命令
find -name "main*"
则没这个烦恼,因为双引号会抑制 Shell 进行通配符展开,将 main* 完整地传递给 find 命令,在终端输入
man find
打开 find 命令帮助文档,输入 /-name 匹配到表达式说明
可以看到 -name 表达式是支持通配符匹配的,而且最后还温馨提示,别忘记加双引号,防止被 Shell 展开(这里可以和之前 starting-point 作对比,路径只有 Shell 支持通配符匹配,find 命令的路径选项是不识别通配符的)
可以发现,加了双引号后,能找到相关文件
ok,先到这里,下篇 blog 继续