115、【OS】【Nuttx】【周边】效果呈现方案解析:重定向命令
【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
接之前 blog
【OS】【Nuttx】【周边】效果呈现方案解析:-print0 选项
【OS】【Nuttx】【周边】效果呈现方案解析:-print0 补充(上)
【OS】【Nuttx】【周边】效果呈现方案解析:-print0 补充(中)
【OS】【Nuttx】【周边】效果呈现方案解析:-print0 补充(下)
详细分析了方案里的 -print0 选项,下面继续来分析效果呈现方案解析
重定向命令
find ~/.vscode-server -path "*/swyddfa.esbonio/sphinx/html" -type d -print0 2>/dev/null
下面再分析下这里的 2>/dev/null,这里可以拆成两部分
- 2> :重定向标准错误输出(stderr)
- /dev/null :空设备,可以理解为一个黑洞,所有写进去的东西都会消失
所以连起来的意思就是把命令的错误信息丢进黑洞,让用户看不见
Linux 每个命令运行时,都有 3 个默认通道:
- 0:标准输入(stdin)
- 1:标准输出(stdout)
- 2:标准错误(stderr)
这里举上个 blog 【OS】【Nuttx】【周边】效果呈现方案解析:-print0 补充(下) 例子
创建 demo 样本文件
touch test1.txt test2.txt $'test\nimportant.txt' important.txt
然后执行不安全处理模式
find . -name "*test*" -print | while IFS= read -r file; doecho "Processing: $file"rm "$file"
done
终端输出如下
可以看到 rm 命令找不到 ./test 文件进行删除(因为恶意文件名藏着换行符,该文件被拆分成两个文件处理),终端会输出报错信息
将 rm 命令后面加入 2>/dev/null
find . -name "*test*" -print | while IFS= read -r file; doecho "Processing: $file"rm "$file" 2>/dev/null
done
重新生成样本文件,再次执行,可以看到终端的报错信息都看不见(丢入黑洞)了
下面再来分析下重定向命令 > 的主体,重定向命令还可以将输出重定向到文件:
- > file.txt:主体默认标准输出,即把 stdout (1) 重定向到文件
- 2> file.txt:主体错误输出,把 stderr (2) 重定向到文件
- &> file.txt:主体标准输出和错误输出,把 stdout 和 stderr 都重定向(Bash 4+ 版本以上支持)
在这个语境下
find ~/.vscode-server -path "*/swyddfa.esbonio/sphinx/html" -type d -print0 2>/dev/null
因为 .vscode-server 目录里可能有:
- 没权限访问的子目录
- 已经被删除的符号链接
- 正在被其他进程使用的文件等
这时 find 命令会输出错误,比如
find: ‘/home/user/.vscode-server/xxx’: Permission denied
find: ‘/home/user/.vscode-server/yyy’: No such file or directory
这些错误不重要,解决方案只想要能找到的目录,所以此时用 2>/dev/null 把这些错误信息静默丢弃
回到脚本中的查找最新构建件函数
40 行这里,完整的语句为
< <(find ~/.vscode-server -path "*/swyddfa.esbonio/sphinx/html" -type d -print0 2>/dev/null)
注意这里是 < <(…),中间有空格,表示重定向 + 进程替换,而不是 <<(…),中间没空格,这不是 bash 语法
下面看整体的 while 循环和 find 命令(查找整体构建件),简化版的代码如下
while read dir; do...
done < <(find /path -type d)
所以这块代码其实是两个独立语法的组合
- < 输入重定向:把右边的东西作为 while 循环的输入,所以重定向命令有两个 < (从右边重定向到左边),> (从左边重定向到右边)
- <(…) 进程替换:运行括号里的命令,返回一个伪文件路径(比如 /dev/fd/63)
所以 40 行的
while read dir; do...
done < <(find ...)
这里 <(find …) 返回伪文件路径 /dev/fd/63,那么上面就等价于
while read dir; do...
done < /dev/fd/63
相当于把 find 的输出当作一个文件来循环读
ok,先分析到这儿,下篇 blog 继续分析