Вопрос по directory, arrays, bash – Как я могу сохранить список каталогов в массиве?

2

Почему это ничего не перечисляет? Спасибо

FOLDER=()

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

echo ${FOLDER[1]}

Ваш Ответ

4   ответа
3

вы также можете сделать что-то вроде

while ....
done <<<$(ls)
Это правильный способ иметь дело как с областью видимости, так и с возможными пробелами в именах файлов.
использованиеfor и шар. Никогда не используйтеls таким образом.
@Raphink, обработка пространства зависит от того, что находится вwhile, Я рекомендуюIFS= read f или некоторые такие
По умолчанию,while использует переводы строк как IFS, аfor отрезки по пробелам, отсюда и мой комментарий.
while не имеет понятияIFS, но да,read помещает все в переменную, если указан только один. Я не помню, в каком случае вам нужно указатьIFS= вread, Может быть, некоторые древние версии нуждались в этом & # x2026;
1

while выполняется в дочерней оболочке и не может изменять родительские переменные, в этом случаеFOLDER, Вы должны попробовать другие способы. Например:

(напечатает второй файл там)

NOTEДа, я понимаю проблемы этого решения, пробелы, использованиеlsи т.д. Я просто хотел указать на проблему сwhile, Чтобы завершить ответ, да, следует использовать сглаживание:

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

И, не умирая от пуризма, обычный (по крайней мере в UNIX)NOT пробелы в именах файлов. Это вредно для вашего здоровья :)

Многие файлы имеют пробелы в своих именах.ls никогда не будет использоваться таким образом. Вместо этого следует использовать шар. Итерации по глобусу с использованиемfor Цикл устраняет необходимость в трубе и, таким образом, не создает подоболочку.
@chepner тогда проблема с пробелами в именах файлов
FOLDER не станет массивом после этого присваивания. И эхо снова будет пустым. Тем не менее, это не совсем правильная вещь.
По крайней мере
(Я отредактировал пост, чтобы сделатьFOLDER массив; Я еще не видел комментарий @ nshy).
8
Analysis

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

Предполагая, что каждая запись в / tmp / backup является каталогом, вы можете просто использовать глобусы оболочки для заполнения вашего массива. Если у вас могут быть как файлы, так и записи в каталоге, вам необходимо использоватьfind или используйте тестовое выражение оболочки, чтобы убедиться, что запись действительно является каталогом. Например:

# 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 вариант, так что глобус не обрабатывается буквально, если каталог пуст.
@ MichaelKrelin-hacker Это просто для того, чтобы сохранить семантику для OP. Вы можете вызывать переменную как угодно, но ваша точка зрения хорошо принята.
@chepner Это отличное предложение; благодарю вас.
0

одной из проблем с кодом выше является изменение переменной в подоболочке. Другой использует+= заполнить массив. К сожалению, это просто добавляет к нулю элемент в виде строки, так чтоFOLDERS[1] остается неопределенным

Это удар! Обратите внимание - я пропустил скобки. @DennisWilliamsonThank you
array+=(element) не добавляет к нулевому элементу в виде строки - он добавляет новый элемент в массив.

Похожие вопросы