0

我试图使用 afor的输出进行迭代ls -R,它只是挂起。

for i in $(ls -R /); do echo $i; done;

是一样的

for i in $(find /); do echo $i; done;

哪里有问题?为什么保持“光标等待”?

4

4 回答 4

2

它暂停的原因是因为首先 $() 被视为首先要计算的变量。因此,它首先进行查找并将所有内容加载到内存中,然后对其进行迭代。

无论如何,循环查找往往不是一个好主意。即使是少量物品。bash for 循环将所有空格视为项目的分隔符。这意味着如果您的任何文件名包含空格,您将得到不希望的结果。相反,我建议使用 find 的内置 exec 选项。

find / -exec echo '{}' \;


正如 Karthik 指出的那样,您还可以将 while 循环与 read 一起使用。

ls -R / | while read i; do
    echo $i
done

这个循环有两个原因。首先,仅在 \n (或 EOF)上读取中断。这意味着带有空格的文件将被计为一个文件。其次,管道确保数据不会堆积。文件名将被循环吃掉,因为它们是由ls生成的。

于 2012-06-10T18:54:49.410 回答
2

“寻找”以外的答案

解析 ls 的输出通常是个坏主意。其他人已经向您展示了如何使用 find。您在 bash 中还有另一个选择:globstar。

shopt -s globstar
for file in /tmp/**; do
    echo "$file"
done

也可以看看

于 2012-06-10T19:02:39.867 回答
1

这是因为变量被读取,加载到 for。

有时,bash 无法在内部处理这些变量。尝试使用这些替代方法以获得最佳效果。

试试这些:

#IO based is best.
ls -R / | while read i ; do
  echo $i
done

(或者)

#in your case
find / -exec echo \{\} \;
于 2012-06-10T18:54:20.663 回答
1

这取决于你想在循环内做什么。管道进入 while 循环的问题是循环内部的任何变量更改在外部都不可见。例如:

x=0
ls -R / | while read i; do
    (( x++ ))
done
echo $x

会给出 0(顺便说一下,ksh 没有这个问题)。一种解决方案是使用 Process Substitution,它使用命名管道一次输入一行,这次循环在线运行:

x=0
while read i; do
    (( x++ ))
done < <(ls -R /)
echo $x

ksh93 也支持这种语法

于 2012-06-11T08:07:52.593 回答