我试图使用 afor
的输出进行迭代ls -R
,它只是挂起。
for i in $(ls -R /); do echo $i; done;
是一样的
for i in $(find /); do echo $i; done;
哪里有问题?为什么保持“光标等待”?
它暂停的原因是因为首先 $() 被视为首先要计算的变量。因此,它首先进行查找并将所有内容加载到内存中,然后对其进行迭代。
无论如何,循环查找往往不是一个好主意。即使是少量物品。bash for 循环将所有空格视为项目的分隔符。这意味着如果您的任何文件名包含空格,您将得到不希望的结果。相反,我建议使用 find 的内置 exec 选项。
find / -exec echo '{}' \;
正如 Karthik 指出的那样,您还可以将 while 循环与 read 一起使用。
ls -R / | while read i; do
echo $i
done
这个循环有两个原因。首先,仅在 \n (或 EOF)上读取中断。这意味着带有空格的文件将被计为一个文件。其次,管道确保数据不会堆积。文件名将被循环吃掉,因为它们是由ls生成的。
解析 ls 的输出通常是个坏主意。其他人已经向您展示了如何使用 find。您在 bash 中还有另一个选择:globstar。
shopt -s globstar
for file in /tmp/**; do
echo "$file"
done
这是因为变量被读取,加载到 for。
有时,bash 无法在内部处理这些变量。尝试使用这些替代方法以获得最佳效果。
试试这些:
#IO based is best.
ls -R / | while read i ; do
echo $i
done
(或者)
#in your case
find / -exec echo \{\} \;
这取决于你想在循环内做什么。管道进入 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 也支持这种语法