find usará os primeiros argumentos (até o primeiro argumento que começa com - ou ! ou ( ) que obtém como os caminhos de nível superior a serem pesquisados. Você está dando find um único argumento quando você o chama na sua função, a string $1 $dir_pattern $file_pattern (com as variáveis expandidas). Este caminho não foi encontrado.
Você também inclui aspas duplas literais nos argumentos que pretende dar a find . É feita uma cotação dupla para evitar que o shell expanda padrões glob e divida em espaços em branco (ou qualquer que seja a variável IFS ), mas se você usar, por exemplo, ! -name \"thing\" , então as aspas duplas seriam parte do padrão que find usa para comparar com os nomes dos arquivos.
Use matrizes e cite os argumentos separados para find corretamente:
myfind () {
local ignore_paths=( "$1" "*foo*" )
local ignore_names=( "one.txt" "two.txt" "*three*.txt" )
local path_args=()
for string in "${ignore_paths[@]}"; do
path_args+=( ! -path "$string" )
done
local name_args=()
for string in "${ignore_names[@]}"; do
name_args+=( ! -name "$string" )
done
find "$1" "${path_args[@]}" "${name_args[@]}"
}
Sempre que adicionamos path_args e name_args acima, adicionamos três elementos à lista, ! , -path ou -name e "$string" . Ao expandir "${path_args[@]}" e "${name_args[@]}" (observe as aspas duplas), os elementos serão citados individualmente.
Implementação equivalente adequada para /bin/sh :
myfind () (
topdir=$1
set --
# paths to ignore
for string in "$topdir" "*foo*"; do
set -- "$@" ! -path "$string"
done
# names to ignore
for string in "one.txt" "two.txt" "*three*.txt"; do
set -- "$@" ! -name "$string"
done
find "$topdir" "$@"
)
No shell sh , temos apenas uma única matriz disponível para nós, que é a lista de parâmetros posicionais, $@ , portanto, coletamos nossas opções find . A solução bash -specific também pode ser escrita para usar uma única matriz, obviamente, e a variação sh seria executada em bash também.
E, por último, a saída do seu echo test não é uma representação precisa do comando que teria sido executado pela sua função.
Considere isso:
cat "my file name"
que executa cat em algo chamado my file name e
echo cat "my file name"
que produz a string cat my file name . Isso se deve ao fato de que o shell remove aspas ao redor das strings antes de executar o comando. Executando o comando , cat procuraria por três arquivos, não um.
Seu comando funcionou bem quando você copiou e colou no shell, porque você incluiu as aspas duplas literais na string que foi gerada por echo (escapando delas), mas esse não era o comando real executado pelo seu função.