Использование массива для `ls --ignore` - PullRequest
1 голос
/ 17 февраля 2020

Я работаю над сценарием bash для резервного копирования моего сервера. Основываясь на моей сети root (/ home), я хочу фильтровать мои веб-каталоги, исключая что-то общее. Я нашел - игнорировать вариант для него. Вот мой код для возврата того, что я хочу.

DIR_LIST=`ls -al $WWW_ROOT --ignore={.,..,ubuntu,test} | grep "^d" | awk '{ print $9 }'`
echo $DIR_LIST;

Но когда я попробовал с массивом, это не сработало.

EXCLUDED=(. .. test ubuntu)
STR=$(IFS=,; echo "${EXCLUDED[*]}")
DIR_LIST=`ls -al $WWW_ROOT --ignore={$STR} | grep "^d" | awk '{ print $9 }'`
echo $DIR_LIST;

echo $ STR работает хорошо, но echo $ DIR_LIST нет. Я думаю, что скобка не работает должным образом.

Как я могу сделать это, как я ожидал?

Ответы [ 3 ]

2 голосов
/ 17 февраля 2020

Вот один из способов сделать это без использования ls, и, что еще хуже, вы используете флаг -al.

#!/usr/bin/env bash

shopt -s nullglob extglob

files=(/path/to/www/directory/!(ubuntu|test)/)

declare -p files

Это покажет вам файлы в назначении массива.

Если вы хотите l oop через файлы и удалить путь к файлу из имени файла без использования каких-либо внешних команд из оболочки.

for f in "${files[@]}"; do echo "${f##*/}"; done 

Который имеет тот же результат при использовании basename

for f in "${files[@]}"; do var=$(basename "$f"); echo "$var"; done 

Или просто сделать это в массиве

printf '%s\n' "${files[@]##*/}"

"${files##*/}" - это форма расширения параметра PE.

Существует онлайн bash руководство, где вы можете посмотреть PE см. Расширение параметра

Или справочную страницу. см. PAGER='less +/^[[:space:]]*parameter\ expansion' man bash

Поиск nullglob и extglob см. globbing оболочки

Массив с именем files теперь содержит данные / файлы, которые вы Заинтересованы.

По умолчанию точечные файлы не указаны в списке, поэтому вам не нужно об этом беспокоиться, если только не включен параметр dotglob, который по умолчанию отключен.

2 голосов
/ 17 февраля 2020

Ваша идея в основном верна, но у нее есть несколько проблем. Во-первых, команда ls использует стиль оболочки для расширения шаблона --ignore. Он отлично работает, когда вы указали это явно.

Но когда вы определяете его в переменной для расширения глобуса, оболочке это не нравится. Потому что, когда оболочка расширяет командную строку, она сначала выполняет глобальное расширение, а затем расширяет переменную. Поскольку у вас есть глобус внутри переменной, к тому моменту, когда он расширяет переменную, он уже перешел точку, где он может расширить глобус, поэтому ваш шаблон --ignore действительно никогда не формируется так, как вы ожидаете.

Кроме того, как вы заполняете массив, не рекомендуется использовать этот подход, потому что это fr agile ( Почему вы не должны анализировать вывод ls(1)), когда дело доходит до работы с именами, включающими пробелы / перевод строки или любые другие метасимволы оболочки.

См. Как исключить каталог в find . команда , чтобы исключить каталоги при поиске в файловой системе.

0 голосов
/ 17 февраля 2020

если "ubuntu" и "test" - это файл, он должен работать. если они являются каталогами, вам нужно добавить точку "." как ".test" или ".ubuntu" в ИСКЛЮЧЕНО

...