命令行重定向作用范围解析:以< <(cmd)与while循环场景为例
Bash中< <(cmd)重定向的作用对象解析
先明确几个核心概念:
- 进程替换
<(cmd):bash会启动cmd进程,把它的标准输出接到一个临时匿名管道(或/dev/fd下的文件描述符),然后返回这个临时"文件"的路径,本质是让其他命令能像读普通文件一样读取cmd的输出。 - 标准输入重定向
<:作用是把指定文件的内容,作为当前命令/代码结构的标准输入。
为什么单独用<(find...)不行?
如果你写while read line; do basename "$line"; done <(find ...),bash会把<(find...)当成while循环的位置参数,而非stdin重定向。while是shell的控制结构,不是外部命令,它不接收位置参数,所以这种写法会触发语法错误——bash不知道该怎么处理这个多余的参数。
< <(cmd)到底把内容传给了谁?
第一个<是标准输入重定向符号,它的作用是把进程替换生成的临时"文件"内容,作为整个while-do-done循环结构的标准输入。
循环里的read命令默认会从当前shell的stdin读取内容,也就是这里被重定向后的循环stdin,所以每次read都会从find的输出里读一行,赋值给变量。
为什么不会被第一个basename接收?
basename是靠命令行参数处理内容的,它根本不会去读标准输入。在你的代码里,basename处理的是$line这个变量(也就是read从循环stdin读来的路径),完全没碰stdin。只有像read、grep这种明确要从stdin读取数据的命令,才会使用循环的stdin。
举个实际的例子:
# 正确写法 while read -r file_path; do # basename处理的是变量$file_path,不是stdin basename "$file_path" done < <(find /home -type f)
这里find的输出全被导向while循环的stdin,只有read会去读这些内容,其他命令只要不是显式读取stdin,就不会动这部分数据。
内容的提问来源于stack exchange,提问作者mazda
相关产品推荐
相关产品推荐

