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.