【发布时间】:2012-07-20 00:09:16
【问题描述】:
为什么这没有列出任何东西?谢谢
FOLDER=()
ls /tmp/backup/ | while read DIR
do
FOLDER+=("$DIR")
done
echo ${FOLDER[1]}
【问题讨论】:
为什么这没有列出任何东西?谢谢
FOLDER=()
ls /tmp/backup/ | while read DIR
do
FOLDER+=("$DIR")
done
echo ${FOLDER[1]}
【问题讨论】:
您的示例旨在失败。例如:
ls的输出。假设 /tmp/backup 中的每个条目都是一个目录,您可以简单地使用 shell glob 来填充您的数组。如果您可能有文件和目录条目,那么您需要使用 find 或使用 shell 测试表达式来确保该条目实际上是一个目录。例如:
# Enable special handling to prevent expansion to a
# literal '/tmp/backup/*' when no matches are found.
shopt -s nullglob
FOLDERS=(/tmp/backup/*)
for folder in "${FOLDERS[@]}"; do
[[ -d "$folder" ]] && echo "$folder"
done
# Unset shell option after use, if desired. Nullglob
# is unset by default.
shopt -u nullglob
【讨论】:
nullglob 选项可能是个好主意,这样如果目录为空,就不会按字面意思处理glob。
要解决 subshellissue(请参阅 Diego 的回答),您还可以执行类似的操作
while ....
done <<<$(ls)
【讨论】:
while 中的内容。我会推荐IFS= read f 或类似的
while 使用换行符作为 IFS,而for 使用空格,因此我的评论。
while 没有IFS 的概念,但是是的,如果只提供一个,read 会将所有内容都放入变量中。我不记得在哪种情况下您需要将IFS= 指定为read。也许一些古代版本需要那个……
ls 输出的想法是一个很好的想法,尽管 OP 遇到的问题不是由于解析,所以我认为解决这个直接问题很重要。
while 在子 shell 中执行,它不能修改父 shell 的变量,在本例中为 FOLDER。你应该尝试其他方法。例如:
FOLDER=(`ls /tmp/backup`)
echo ${FOLDER[1]}
(将在那里打印第二个文件)
注意:是的,我理解这个解决方案的问题,空格,ls 的使用等。我只是想指出while 的问题。要完成答案,是的,应该使用通配符:
for dir in /tmp/backup/* ; do
test -d "$dir" && do_stuff_with_dir("$dir")
done
而且,由于不死于纯粹主义,通常(至少在 UNIX 中)不在文件名中包含空格。这对你的健康有害:)
【讨论】:
FOLDER 成为一个数组;我还没有看到@nshy 的评论)。
ls 不应该以这种方式使用。应改为使用 glob。使用 for 循环对 glob 进行迭代消除了对管道的需求,因此不会创建子外壳。
正如其他人已经提到的,上面代码的问题之一是修改子shell中的变量。另一种是使用+= 来填充数组。不幸的是,这只是作为字符串添加到第零个元素,因此FOLDERS[1] 保持未定义。
【讨论】:
array+=(element) 不会作为字符串添加到第零个元素 - 它会将新元素附加到数组中。