首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cmd_drain <(cmd_src)和cmd_drain <<< "$(cmd_src)“之间有什么区别吗?

cmd_drain <(cmd_src)和cmd_drain <<< "$(cmd_src)“之间有什么区别吗?
EN

Unix & Linux用户
提问于 2019-01-15 10:04:59
回答 1查看 381关注 0票数 6

众所周知,cmd | read -r var1 var2构造在bash中不工作,因为由于管道的原因,读取命令在子subshell中执行。我过去经常使用read -r var1 var2 <<< "$(cmd)"来解决这个问题,但最近我了解了cmd_drain < <(cmd_src)构造,它似乎也同样有效:read -r var1 var2 < <$(cmd)

这两种解决方案有什么区别吗?在微不足道的情况下,似乎没有任何区别:

代码语言:javascript
复制
$ hd < <(echo Hello)
00000000  48 65 6c 6c 6f 0a                                 |Hello.|
00000006
$ hd <<< $(echo Hello)
00000000  48 65 6c 6c 6f 0a                                 |Hello.|
00000006

我也尝试了一些特殊的角色,并得到了同样的结果。我的直觉是,结果总是一样的,cmd_drain <<< "$(cmd_src)"将首先运行cmd_src并在内存中缓冲整个结果,然后再将其输入cmd_drain,而cmd_drain < <(cmd_src)将继续将cmd_src的输出输入cmd_drain。我假设它的行为类似于cmd_src | cmd_drain,只是cmd_src将在子shell中运行,而不是在cmd_drain中运行。我的假设正确吗?

附加问题:围绕$()结构引用是否必要?

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2019-01-15 10:21:36

是的,你的假设是正确的。在cmd_drain < <(cmd_src) (又称过程替代,结合普通重定向)中,Bash将用文件路径代替<(cmd_src),从该路径可以读取cmd_src的输出。从医生那里:

进程列表异步运行,其输入或输出显示为文件名。作为展开的结果,此文件名作为参数传递给当前命令。如果使用>(list)表单,写入文件将为列表提供输入。如果使用<(list)表单,则应读取作为参数传递的文件以获得列表的输出。

cmd_drain <<< "$(cmd_src)"中,<<< ...与任何其他这里-字符串一样被对待,因此:

该词经历了倾斜展开、参数和变量展开、命令替换、算术扩展和移除引号。不执行路径名称展开和字拆分。结果以单个字符串的形式提供,并附加一个新行到其标准输入的命令中。

因此,您不需要引用$(),特别是因为这里的字符串<<<语法不进行分词或文件名扩展。通常,你必须这么做。

请再次注意此处字符串文档的最后一句--一个换行符被追加:

代码语言:javascript
复制
bash-5.0$ od -c <<< $(printf %s foo)
0000000   f   o   o  \n
0000004
bash-5.0$ od -c < <(printf %s foo)
0000000   f   o   o
0000003

这件事是否重要取决于你在做什么。

hd <<< $(echo Hello)中,命令替换移除echo的尾随换行符输出,这里的字符串添加了一个换行符,从而有效地为您提供了相同的输出。但是,正如上面的示例所示,删除/添加换行符可能很棘手,您不需要精确地获得cmd_src输出。

票数 10
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/494574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档