Estou tentando escrever um script find
que mais tarde poderá ler uma lista de diretórios a serem excluídos de um arquivo externo. Embora eu possa realizar essa parte sozinho, é a expansão da matriz irritante que torna a tarefa difícil.
Primeiro, algumas "preparações" para obter uma árvore de diretórios de amostra adequada:
$ mkdir tmp && cd tmp
$ mkdir excl1_dirx excl2_dirx excl3_dirx
$ touch excl1_dirx/dummy1.txt excl2_dirx/dummy2.txt excl3_dirx/dummy3.txt
$ mkdir excl1_diry excl2_diry excl3_diry
$ touch excl1_diry/dummy4.txt excl2_diry/dummy5.txt excl3_diry/dummy6.txt
$ touch dummy00.txt dummy01.txt
Se o script funcionar, apenas dummy00.txt
e dummy01.txt
poderão ser exibidos.
#!/bin/bash
excl_d=("excl*_dirx" "excl*_diry")
find_str=" . -type f ! ( "
for ((i=0 ; i<$((${#excl_d[*]})) ; i++)); do
if [[ $i > 0 ]]; then
find_str+=" -o "
fi
find_str+=" -path \"./${excl_d[i]}/*\""
done
find_str+=" )"
# this is just for debugging
echo "[debug] value of str = find $find_str"
find $find_str
Primeiro de tudo: por que (aparentemente) complicado na linha antes do " done
"? Bem, bash
às vezes gosta de incomodar os usuários fazendo coisas que eles não esperam. Sem essas citações, expandirá cada elemento da matriz; e. g. excl*_dirx
se tornará excl1 dirx excl2 dirx excl3 dirx
, o que (obviamente) quebra a linha -path
! E que, embora eu tenha usado um par de aspas duplas por elemento de matriz, o que na verdade deveria impedir que o bash fizesse seu mal de expansão!
No entanto, o melhor ainda está por vir: a segunda última linha - quando o (
)
é escapado para \(
\)
- funcionará bem no shell, mas não em um script autônomo. Mesmo que isso não cause erros, o resultado da última implementação estará errado.
Eu tentei todos os tipos de combinações com aspas simples e duplas no
find_str+=" -path \"./${excl_d[i]}/*\""
linha, mas eu simplesmente não consigo fazê-lo funcionar, embora pareça absolutamente perfeito quando exibido como na segunda última linha. Parece que bash
trata internamente minhas cotas de escape \"
de maneira diferente das não escapadas. Ah, e as citações dentro das citações funcionam perto de todos os lugares mas por algum motivo, serão filtradas quando o operador +=
for usado.
Não estou apenas procurando uma explicação para esse comportamento, mas também para uma solução de como isso poderia funcionar em um script autônomo. Deve ser um erro estúpido que eu cometi. : - /