найдите с пользовательскими переменными

Хорошо, если Вы хотите проверить, используется ли диск в качестве устройства набега md (и просто не в настоящее время активный), единственный безопасный способ сделать это состоит в том, чтобы работать mdadm -E /dev/sdX

Однако, если Вы не заботитесь о том, что находится на диске (если Вы собираетесь вытереть его так или иначе), затем он не имеет значения так или иначе.

1
27.10.2012, 16:43
3 ответа

Содержание FILENAME переменная

-regex .*test.*

Кавычки не являются частью значения переменной, они - часть синтаксиса оболочки. Оболочка проанализировала строку, интерпретировав кавычки, прежде чем она даже видела, что это было присвоение.

Когда Вы затем выполняете строку find $DIRECTORY $FILENAME, $FILENAME сначала заменяется его значением. Затем оболочка выполняет два шага расширения на значении переменной: это разделяет его на отдельные слова, где переменная содержит пробел (который Вы, оказывается, хотите), и это выполняет globbing (т.е. подстановочное расширение) на каждом слове, таким образом, .* расширен до списка имен файлов в текущем каталоге, которые начинаются с точки.

Вы не сталкивались с проблемами со своим первым отрывком потому что шаблон .*test.* произошедший для не соответствия любому файлу, таким образом, это расширилось до себя.

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

DIRECTORY="./"
EXPRESSION=("-regex" ".*test.*")
find "$DIRECTORY" "${EXPRESSION[@]}"

или если Вы хотите позволить несколько каталогов:

DIRECTORIES=("./")
EXPRESSION=("-regex" ".*test.*")
find "${DIRECTORIES[@]}" "${EXPRESSION[@]}"

"${EXPRESSION[@]}" расширяется до списка элементов в массиве, в отдельных словах.

Обратите внимание, что необходимо всегда использовать двойные кавычки вокруг подстановок переменных "$foo" и команда susbtitutions "$(foo)", если Вы не знаете, что хотите, чтобы разделение слова и globbing произошли со значениями.

Здесь, так как Вы используете удар, массив является правильным решением. В оболочке, которая не имеет массивов, существует несколько возможностей. Можно использовать позиционные параметры, которые являются эффективно переменной типа массив, но это - только возможность, если Вы не используете их для чего-то еще:

set -- "./"                  # start with the directory
set -- "$@" -regex '.*'      # add the expression
find "$@"                    # go

Другой метод должен правильно заключить содержание в кавычки переменной для подготовки его к более позднему разделению слова и globbing. Можно использовать обратную косую черту перед подстановочным символом (?*[) заставить его интерпретироваться буквально.

DIRECTORY=./
EXPRESSION='-regex .\*'
find "$DIRECTORY" $EXPRESSION

Другой метод должен отключить globbing с set -f. прежде, чем выполниться find строка. Обязательно снова включите его с set +f если Вам нужен он впоследствии. Обратите внимание, что, так как Вы используете разделение слова, Вы не сможете поместить пробельные символы как часть аргумента a find предикат.

DIRECTORY=./
EXPRESSION='-regex .*'
set -f
find "$DIRECTORY" $EXPRESSION

См., что также я пытаюсь поместить команду в переменную, но сложные случаи всегда перестали работать! в ударе FAQ.

1
28.01.2020, 02:09

Также

directory=.
match=(-regex '.*test.*')
find "$directory" "${match[@]}"

Или (сюда использование"", только для высказывания мнения):

directory=.
match='-regex,.*test.*'
IFS=,
set -f
find "$directory" $match

Или:

directory=.
match="-regex '.*test.*'"
eval 'find "$directory" '"$match"
0
28.01.2020, 02:09

Вы не заключаете переменные в кавычки. Поэтому то, что видит оболочка,

find ./  -regex .*

И это расширяется .* кому: . ...

-1
28.01.2020, 02:09
  • 1
    поэтому, как это должно быть? –  Bartlomiej Lewandowski 27.10.2012, 16:40
  • 2
    Например: DIRECTORY='./' ; FILENAME='-regex ".*/p.*"' ; eval find $DIRECTORY $FILENAME. –  choroba 27.10.2012, 16:45

Теги

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