【问题标题】:Bash - Why do these two commands in a loop run in succession rather than parallel?Bash - 为什么循环中的这两个命令连续运行而不是并行运行?
【发布时间】:2015-03-19 20:15:39
【问题描述】:

我正在尝试一些 bash,但我无法弄清楚以下行为。我有一个 for 循环,似乎一个命令在另一个命令开始之前运行整个循环,即使它们在同一个 dodone 结构内。看我的例子:

这是 shell 脚本:

for i in "$(ls .)"
do
    printf "$i\n"
    printf "$i\n"
done

如果这是在包含文件 abc 的目录中运行的,我希望输出为:

a
a
b
b
c
c

而是:

a
b
c
a
b
c

谁能给我解释一下这是怎么回事?

【问题讨论】:

    标签: bash loops


    【解决方案1】:

    因为您在将$(ls .) 中的表达式传递给循环之前对其进行了扩展,所以它首先评估所有目录中的文件,然后将其打印两次。本质上,您的循环只包含一个您打印两次的元素。

    你想要的行为可以通过使用 glob * 操作符来获得:

    for i in *
    do
        printf "$i\n"
        printf "$i\n"
    done
    

    这样* 表示要迭代的列表,而不是已经评估的字符串。

    【讨论】:

    • 谢谢,这绝对可以解决问题。现在我很好奇,为什么printf 中的换行符在每个文件之后呢?而不是在最后一个文件名之后?
    • 好问题 - 我自己也不太确定。几乎看起来ls 命令以换行符终止每个文件名。引用时,这些被保留。但是,直接在控制台中键入命令时显然不是这种情况。我无法回答为什么在子外壳中执行时会发生这种行为。这里有更多关于 subshel​​l 的信息:tldp.org/LDP/abs/html/commandsub.html 看看第二个警告。
    • @GeorgeYates:因为ls 每行打印一个文件名除非 stdout 被重定向到终端。在交互式外壳中,它是,并且您会得到压缩的列列表。请参阅ls-1-C 选项(还有更多选项请参见-m-x。)
    • 谢谢,这就解释了。如此微妙。
    猜你喜欢
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多