Usar o find com -exec rm em um script bash falha, mas funciona no prompt

0

Isso está me deixando louca, pois sei que é algo fácil, mas não consigo encontrar a solução. Arrgh! Eu só preciso adicionar um comando find no meu script para que ele remova arquivos antigos antes de executar um novo backup. Eu prefiro controlar isso através de variáveis em vez de digitar o comando exato. O comando funciona no script se eu digitá-lo lá em vez de usar variáveis.

FIND="/usr/bin/find"
BUILD="~/"
FINDOPTS="-type f -mtime +3 -exec rm -rf {} \;"
echo $find $BUILD $FINDOPTS
## remove the 2 week old backup
echo "Removing old backups... "
$FIND $BUILD $FINDOPTS

Se eu apenas ecoar o comando $FIND $BUILD $FINDOPTS , ele será mostrado exatamente como o comando faz se eu digitá-lo. A única diferença é que ele será executado quando eu digitá-lo.

Digitar /usr/bin/find ~/ -type f -mtime +3 -exec rm -rf {} \; funciona muito bem.

O erro que recebo é:

/usr/bin/find: missing argument to '-exec'

Alguém pode ajudar a explicar por que isso acontece? Obrigado!

    
por saleetzo 27.03.2018 / 21:43

2 respostas

3

Não obstante as melhores soluções gerais, eis o motivo pelo qual ele falhou neste script:

FINDOPTS="-type f -mtime +3 -exec rm -rf {} \;"
                                            ^

O parâmetro find está aguardando é o caractere ; . Como ; é (não por acaso) também o delimitador de fim de comando do shell, ele deve ser escapado em um comando shell, portanto, geralmente digitado \; . Se agora você colocar este caractere em uma variável, ele nunca será avaliado pelo shell como um delimitador. Assim, o musn't deve ser salvo.

Reproduzindo o erro sem variável:

$ find /etc -exec ls "\;"
find: missing argument to '-exec'

Portanto, basta substituir a string por:

FINDOPTS="-type f -mtime +3 -exec rm -rf {} ;"
    
por 27.03.2018 / 23:03
2

Em vez de find [...] -exec rm , sugiro usar a funcionalidade incorporada:

find [...] -delete

Do manual:

 -delete
         Delete found files and/or directories.  Always returns true.  This executes 
         from the current working directory as find recurses down the tree.  It will 
         not attempt to delete a filename with a ''/'' character in its pathname 
         relative to ''.'' for security reasons.  Depth-first traversal processing 
         is implied by this option.  Following symlinks is incompatible with this 
         option.

(como um aparte, você percebe que o comando em sua pergunta irá deletar algum arquivo com mais de três dias desde a última modificação, sim?)

    
por 27.03.2018 / 21:59