How can I store a list of directories in an array?

2020-03-30 02:36发布

Why this does not list anything? Thank you

FOLDER=()

ls /tmp/backup/ | while read DIR
do
    FOLDER+=("$DIR")
done

echo ${FOLDER[1]}

4条回答
在下西门庆
2楼-- · 2020-03-30 03:21

Analysis

Your example is designed to fail. For example:

  • Don't parse the output of ls.
  • Don't assume every entry in a directory is a directory.
  • Don't append arrays in a loop without a good reason.
  • Don't use unquoted variables.

Use Shell Globs

Assuming that every entry in /tmp/backup is a directory, you can simply use shell globs to populate your array. If you may have files as well as directory entries, then you'll need to use find or use a shell test expression to ensure that the entry is actually a directory. For example:

# 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
查看更多
萌系小妹纸
3楼-- · 2020-03-30 03:23

As the others already mentioned one of the problems with the code above is modifying of a variable in a subshell. The other is using += to populate the array. Unfortunately this just adds to zeroth element as a string, so that FOLDERS[1] stays undefined.

查看更多
Viruses.
4楼-- · 2020-03-30 03:27

To work around subshellissue (see Diego's answer), you can also do something like

while ....
done <<<$(ls)
查看更多
够拽才男人
5楼-- · 2020-03-30 03:36

while gets executed in a child shell, and it cannot modify parent's variables, in this case, FOLDER. You should try other ways. For example:

FOLDER=(`ls /tmp/backup`)
echo ${FOLDER[1]}

(will print the second file in there)

NOTE: Yes, I understand the problems of this solution, spaces, use of ls, etc. I just wanted to point out the problem with while. To complete the answer, yes, globbing should be used:

for dir in /tmp/backup/* ; do
    test -d "$dir" && do_stuff_with_dir("$dir")
done

And, by not dying of purism, the usual (at least in UNIXes) is NOT having spaces in filenames. It is bad for your health :)

查看更多
登录 后发表回答