O conteúdo da variável FILENAME
é
-regex .*test.*
As aspas não fazem parte do valor da variável, elas fazem parte da sintaxe do shell. O shell analisou a linha, interpretando as citações, antes mesmo de ver que era uma atribuição.
Quando você executa a linha find $DIRECTORY $FILENAME
, $FILENAME
é primeiro substituído por seu valor. Em seguida, o shell executa duas etapas de expansão no valor da variável: divide-a em palavras separadas, onde a variável contém espaço em branco (que você deseja) e executa globbing (ou seja, expansão curinga) em cada palavra, portanto .*
é expandido para a lista de nomes de arquivos no diretório atual que começam com um ponto.
Você não teve problemas com o primeiro snippet porque o padrão .*test.*
não coincidiu com nenhum arquivo, por isso expandiu para si mesmo.
A solução robusta é usar uma variável de array em vez de uma variável de string quando você precisa armazenar várias palavras.
DIRECTORY="./"
EXPRESSION=("-regex" ".*test.*")
find "$DIRECTORY" "${EXPRESSION[@]}"
ou se você quiser permitir vários diretórios:
DIRECTORIES=("./")
EXPRESSION=("-regex" ".*test.*")
find "${DIRECTORIES[@]}" "${EXPRESSION[@]}"
"${EXPRESSION[@]}"
expande para a lista de elementos na matriz, em palavras separadas.
Note que você deve sempre usar aspas duplas em torno das substituições de variáveis "$foo"
e do comando susbtitutions "$(foo)"
, a menos que você queira que a divisão de palavras e globbing aconteçam com os valores.
Aqui, como você está usando o bash, um array é a solução certa. Em um shell que não possui arrays, existem várias possibilidades. Você pode usar os parâmetros posicionais, que são efetivamente uma variável de matriz, mas isso é apenas uma possibilidade se você não estiver usando-os para outra coisa:
set -- "./" # start with the directory
set -- "$@" -regex '.*' # add the expression
find "$@" # go
Outro método é citar corretamente o conteúdo da variável para prepará-lo para a divisão posterior de palavras e globbing. Você pode usar uma barra invertida antes de um caractere curinga ( ?*[
) para fazê-lo ser interpretado literalmente.
DIRECTORY=./
EXPRESSION='-regex .\*'
find "$DIRECTORY" $EXPRESSION
Outro método é desativar o globbing com set -f
. antes de executar a linha find
. Certifique-se de ligá-lo novamente com set +f
se você precisar dele depois. Observe que, como você está usando a divisão de palavras, não poderá colocar caracteres de espaço em branco como parte de um argumento para um predicado find
.
DIRECTORY=./
EXPRESSION='-regex .*'
set -f
find "$DIRECTORY" $EXPRESSION
Veja também estou tentando colocar um comando em uma variável, mas os casos complexos sempre falham! no bash FAQ.