当前位置:  开发笔记 > 编程语言 > 正文

为什么在bash中将stdin重定向到while循环中?

如何解决《为什么在bash中将stdin重定向到while循环中?》经验,为你挑选了1个好方法。

请考虑以下示例脚本:

#!/bin/sh

do_something() {
    echo $@
    return 1
}

cat < sample.text
This is a sample text
It serves no other purpose
EOF

cat sample.text | while read arg1 arg2 arg3 arg4 arg5; do
    ret=0
    do_something "$arg1" "$sarg2" "$arg3" "$arg4" "$arg5" <&3 || ret=$?
done 3<&1

重定向stdout为filedescriptor 3的输入的目的是什么?至少在Bash,如果省略它似乎没有任何区别.如果它在任何其他shell中执行,它会有什么影响bash吗?

UPDATE

对于那些想知道它来自哪里的人来说,它是来自Debian cryptdisks_start脚本的简化示例.



1> Charles Duff..:

这里明确的意图是通过确保其标准输入来自其他地方来防止do_somethingsample.text流中读取.如果您在使用或不使用重定向时没有看到行为上的差异,那是因为do_something实际上并不是从测试中的stdin读取.

如果你有两个read并且do_something从相同的流中读取,那么所消耗的任何内容do_something都不会被后续实例使用read- 当然,你会在输入时输入非法内容do_something,从而产生诸如正在尝试加密密钥(如果现实世界的用例类似cryptmount),&c.

cat sample.text | while read arg1 arg2 arg3 arg4 arg5; do
    ret=0
    do_something "$arg1" "$sarg2" "$arg3" "$arg4" "$arg5" <&3 || ret=$?
done 3<&1

现在,它是错误的 - 与之3<&1相比是不好的做法3<&0,因为它假设没有基础,stdout也可以用作输入 - 但它确实成功实现了这一目标.


顺便说一句,我会写更多如下:

exec 3 ...while the loop is run with sample.txt on FD 0

exec 3<&-                        ## close FD 3 when done.

它有点冗长,需要显式关闭FD 3,但这意味着如果我们运行stdout连接到FIFO(或任何其他只写接口)的只写端,我们的代码就不会再被破坏了而不是直接到TTY.


至于这种做法阻止的错误,这是一个非常常见的错误.请参阅以下有关它的StackOverflow问题:

读取行循环后的Shell脚本在第一行后停止

ssh在bash中突然出现while循环

Bash while循环无缘无故停止?

等等

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有