111、【OS】【Nuttx】【周边】效果呈现方案解析:-print0 选项
【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
接之前 blog
【OS】【Nuttx】【周边】效果呈现方案解析:查找最新构建件
分析了解决方案的核心之一,就是要找到最新的构建渲染产物,然后分析了一些命令,其中 find 还没分析完,下面继续,当然,基于的脚本还是在之前 blog 里面
【OS】【Nuttx】【周边】文档构建渲染:效果呈现
方案解析
上篇 blog 分析到 <(…) 中的命令
find ~/.vscode-server -path "*/swyddfa.esbonio/sphinx/html" -type d -print0 2>/dev/null
并且分析到 -print0 选项,这里涉及到 find 命令的结构
find [路径] [条件] [动作]
这里的 -print 就属于动作,将 find 查找的结果打印到终端,这里的动作除了 -print,还有 -delete(找到后删除),-exec(找到后执行后面的命令),-ls(找到后列出详细信息,比如权限、大小、时间等,就像 ls 命令一样)
终端中输入
find --help
可以看到默认路径是当前目录,默认动作是 -print,打印到终端上
这里有个点,上面提到的选项是 -print0,而这里一直说的是 -print,这里其实 -print0 是 -print 的变体
- -print:默认输出路径
- -print0:用 \0 分隔输出
- -printf:自定义格式输出,比如 %p %s bytes\n,这里 %p 表示的是文件路径 path,find 命令会从找到的信息中将文件路径用 %p 格式化输出,%s 表示的是文件大小(字节)size,同样,find 命令也会从找到的信息中将文件大小用 %s 格式化输出
那么现在又有个关键点了,上面的脚本中,用的是 -print0 选项,而不是 -print 默认选项,这个就主要涉及脚本程序的鲁棒性了,可以这么理解
- -print:打印出来给人看的,能在终端友好呈现
- -print0:打印出来给程序看的,保证脚本安全
可以这么类比
- 普通插座:给手机充电
- 工业插座:给机器供电
-print0 是机器接口,-print 是人类接口
另外,上面提到了脚本安全,下面解释下,首先要分辨下 -print 和 -print0 功能上的差别
- -print:输出文件路径,后面加一个换行符 \n,终端显示中换行符是比较常见的,方便辨识查找项,所以上面说是打印给人看的
- -print0:输出文件路径,后面加一个空字符 \0,这种方式在终端中显示效果很差,不是给人看的,但是给机器程序看却很合适
在 Linux 或 类 Unitx 系统中,文件名可以包含空格,制表符,甚至换行符,这种情况虽然少见,但合法(关于这个点,下篇 blog 再介绍),但是文件路径中不可能包含 \0(null 空字符),因为在 C 语言和操作系统中,\0 是字符串的结束标志
实际上,人们一般不会创建一个名字带空格,制表符,换行符的文件,但是人们不创建,不代表程序不会创建,比如有些程序或脚本可能会
- 自动生成文件名,比如从某些网页标题中生成
- 处理用户输入时没过滤换行符
- 某些文档管理系统导出时保留原始格式
此时如果不做处理,程序就会生成带这些符号的文件名
此外,处理这些输入信息的 Bash 处理脚本常常运行部署在:
- 自动化部署
- CI/CD 流水线
- 服务器维护
- 用户不可控的环境
这些地方,如果这些带符号的文件名没有经过处理,就被喂入处理环境,可能就会导致意想不到的后果
而经过上面的分析,用 \0 分隔 find 查找到的信息是100% 安全的,此时 -print0 的作用就体现出来了,可以让 find 命令能安全地输出包含这些换行符,空格,制表符等特殊字符的文件路径,后续的处理脚本,或工具命令等就可以通过 \0 分隔符来正确解析这些文件路径
ok,今天先到这里,下篇 blog 继续