【问题标题】:Redirecting output of bash for loop重定向bas​​h for循环的输出
【发布时间】:2013-09-04 11:28:09
【问题描述】:

我有一个简单的 BASH 命令,看起来像

for i in `seq 2`; do echo $i; done; > out.dat

运行时seq 2 的输出被输出到终端,没有任何内容输出到数据文件(out.dat)

我希望标准输出被重定向到 out.dat 就像它只是运行命令 seq 2 > out.dat

【问题讨论】:

    标签: linux bash shell


    【解决方案1】:

    删除分号。

    for i in `seq 2`; do echo "$i"; done > out.dat
    

    建议

    正如 Fredrik Pihl 所建议的,尽量不要在不需要时使用外部二进制文件,或者至少在实际上不需要时:

    for i in {1..2}; do echo "$i"; done > out.dat
    for ((i = 1; i <= 2; ++i )); do echo "$i"; done > out.dat
    for i in 1 2; do echo "$i"; done > out.dat
    

    另外,请注意words 中可能导致路径名扩展的输出。

    for a in $(echo '*'); do echo "$a"; done
    

    将显示您的文件,而不仅仅是文字 *

    $() 也被推荐为在 Bash 和 POSIX shell 中比反引号 (`) 更清晰的命令替换语法,它支持嵌套。

    将输出读取到变量的更简洁的解决方案是

    while read var; do
        ...   
    done < <(do something)
    

    read ... < <(do something)  ## Could be done on a loop or with readarray.
    
    for a in "${array[@]}"; do
        :
    done
    

    就预期功能而言,使用 printf 也可以是一种更简单的替代方法:

    printf '%s\n' {1..2} > out.dat
    

    【讨论】:

    • 为什么是seq 而不是for i in {1..2}; do ...
    • @FredrikPihl 是的,它更好。或(( i = 1 ; i &lt;= 2; ++i )),或只是in 1 2 以实现兼容性。我的回答只是关于重定向的问题,尽管我试图解决一个问题:"$i"
    • 我只是想你可以用另一种更好的方法来更新你的答案,而不是求助于使用外部二进制文件:-)
    • @FredrikPihl 好吧,这与问题并没有真正的联系,而是更多的建议,但我还是做了更新。
    • 这个例子让我意识到我可以通过管道将done 语句传递给sort 等其他内容,例如for i in foo bar baz; do echo $i | base64; done | sort | base64 -d
    【解决方案2】:

    试试:

    (for i in `seq 2`; do echo $i; done;) > out.dat
    

    【讨论】:

    • 不必将它放在子shell 上。只需删除分号即可使重定向成为块的一部分。
    • 没错,在这种情况下,只需删除分号即可。子shell ( ) 可用于收集大量命令的输出,例如多个 for 循环。
    • 在 stackoverflow 上找不到好的 subshel​​l 文章。这是一个外部:tldp.org/LDP/abs/html/subshells.html
    • @svante 我同意将其封闭起来以获取更多命令,但您也可以使用{} 来执行此操作,因为不需要为子shell 创建另一个进程并保留来自更高块的变量更改.只有在无法解决的情况下才会将它们放在管道上,因为默认情况下它们被放置在子shell上,其中没有设置 laspipe 并且命令在最后,尽管使用进程替换是要走的路它。
    • for 循环已经是一个组合其主体的复合命令;这里的 subshel​​l 毫无意义。
    【解决方案3】:

    另一种可能性,为了完整起见:您可以将输出移动到循环内,使用&gt;&gt; 附加到文件(如果存在)。

    for i in `seq 2`; do echo $i >> out.dat; done;
    

    哪个更好当然取决于用例。一口气写完文件肯定比追加一千次要好。此外,如果循环包含多个echo 语句,所有这些语句都应该进入文件,那么执行done &gt; out.dat 可能更具可读性和更易于维护。当然,这种解决方案的优势在于它提供了更大的灵活性。

    【讨论】:

    • 在循环外做一个重定向肯定对性能更好。
    猜你喜欢
    • 2015-11-27
    • 2017-10-25
    • 2013-05-20
    • 2017-03-12
    • 2013-06-11
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多