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.