Quero usar rsync
para remover certos arquivos (para excluir com eficiência um diretório grande contendo milhares de arquivos ), neste caso, dado a um script de shell como padrões na linha de comando.
Até agora, isso é o que eu tenho no meu script de shellrsync_del.sh
#!/bin/bash
TARGET_DIR=${1}
shift
PATTERNS="${@}"
for patt in ${PATTERNS} ; do
# Both do the same
#INCLUDE_PATTERNS="${INCLUDE_PATTERNS}"' --include='\'"${patt}"\'
INCLUDE_PATTERNS="${INCLUDE_PATTERNS} --include=\"${pattern}\""
done
EMPTYDIR=$(mktemp -d)
echo "Created empty dir ${EMPTYDIR}"
comm="rsync -a --progress --delete ${INCLUDE_PATTERNS} ${EMPTYDIR}/ ${TARGET_DIR}"
echo ${comm}
eval ${comm}
Padrões de exemplo que eu gostaria de usar são *[1-9].txt
, *000??9.txt
. O problema é que, ao executar
rsync_del.sh trg_dir '*[1-9].txt'
a linha de comando gerada é
rsync -a --progress --delete --include='*[1-9].txt' /tmp/tmp.51R9hPgkfG/ trg_dir/
(o que parece ok para mim), mas está combinando, por exemplo, arquivos como input.dat
(e eu não quero isso).
Qual é a maneira correta de implementar/usar isso? Suspeito que seja uma questão de escapar adequadamente dos padrões, mas não consegui fazer isso funcionar.
Obs: Preciso definir o comando a ser executado em uma variável, echo
antes de executar.
Não olhando muito de perto o uso real de
rsync
aqui e, em vez disso, concentrando-se na criação darsync
linha de comando.Ao usar um array (o
incl
array acima), você armazena os argumentosrsync
separadamente e não como uma string. A expansão de"${incl[@]}"
serão os elementos citados individualmente do array. Citar os argumentos torna-se trivial e não há necessidade de chamareval
. Observe também que todas as expansões de parâmetros precisam ser devidamente aspas duplas.O problema com seu código é que você usa a maioria das expansões de parâmetro sem aspas. Isso faz com que o shell execute a divisão de palavras e a geração de nome de arquivo (globbing) nas variáveis. Isso, por sua vez, significa que você não pode usar padrões contendo espaços ou padrões de globbing de shell que podem se expandir para nomes de arquivos existentes.
Pois
/bin/sh
a sintaxe fica ainda menos detalhada:Esqueci que deveria fechar a lista de padrões excluindo qualquer coisa que não estivesse explicitamente incluída. eu usei