rm comando no script bash não funciona com variável

3

Eu estou fazendo um script bash para criar um back-up dos meus bancos de dados mysql. Na verdade, gostaria de excluir os antigos.

Então, eu crio meu script com variável para manutenção.

O roteiro inteiro está realmente funcionando, a única coisa que não funciona é a exclusão dos antigos. Eu estava pensando que seria a parte mais fácil.

De qualquer forma, aqui está o meu código, alguém pode me dizer o que está errado? E o comando rm me retorna: rm: impossible de supprimer « /path/to/backup/files/*.gz »: Aucun fichier ou dossier de ce type O que significa rm: impossible to delete « /path/to/backup/files/*.gz »: no files or directory of this type

Mas o que é realmente estranho, primeiro é que encontrei o script em um tutorial

Dois, que se eu me lançar o "rm /path/to/backup/files/*.gz" em um comando shell, isso está funcionando e excluindo todos os arquivos .gz (como esperado)

#!/bin/bash

USER="***"
PASSWORD="****"
OUTPUT="/path/to/backup/files"

rm "$OUTPUT/*.gz"

databases='mysql --user=$USER --password=$PASSWORD -e "SHOW DATABASES;" | tr -d "| " | grep -v Database'

for db in $databases; do
    if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] && [[ "$db" != "performance_schema" ]] ; then
        echo "Dumping database: $db"
        mysqldump --force --opt --user=$USER --password=$PASSWORD --databases $db > $OUTPUT/'date +%Y%m%d'.$db.sql
        gzip $OUTPUT/'date +%Y%m%d'.$db.sql
    fi
done

Obrigado,

    
por vekah 28.11.2016 / 15:41

3 respostas

-1

Uma maneira alternativa é combinar rm com find e / ou xargs. Estas são algumas alternativas:

find "$output" -name *.gz -type f -delete
find "$output" -name "*.gz" -type f -exec rm '{}' \;
find "$output" -name *.gz -type f -print0 | xargs -0 rm

PS: type f significa procurar por arquivos.

Por padrão, encontre pesquisas em todos os subdiretórios. Você pode limitar a operação find ao diretório atual, se necessário, usando a opção maxdepth:

find "$output" -maxdepth 1 -name "*.gz" -type f -exec rm '{}' \;

Se você precisa continuar trabalhando com rm e uma variável, isso funcionou para mim em uma linha:

out="/home/gv/Desktop/PythonTests/appsfiles";rm "$out"/*.txt
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/a.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/a ver 1.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/b.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/c.txt'? y
rm: remove regular file '/home/gv/Desktop/PythonTests/appsfiles/d.txt'? y
    
por 28.11.2016 / 15:57
10

O

rm "$OUTPUT/*.gz"
A linha de comando

do shell diz ao shell para executar /bin/rm com dois argumentos: rm e /path/to/backup/files/*.gz .

O espaço, " e $ são caracteres especiais na sintaxe da linguagem da shell. Espaço é usado para delimitar argumentos de comando, " é usado para citar outros caracteres especiais (não todos, $ , por exemplo, ainda é especial) assim como * acima e $ é usado para algumas expansões (como o % de expansão do parâmetro$OUTPUT que você está usando aqui).

rm , uma vez iniciado, tentará remover esse arquivo /path/to/backup/files/*.gz . Se esse arquivo não existir (como é o caso de você), ele reportará um erro.

Quando você escreve:

rm /path/to/backup/files/*.gz

ou

rm "$OUTPUT"/*.gz

Como * não é citado desta vez, ele aciona outro recurso especial do shell chamado globbing ou geração de nome de arquivo ou expansão de nome de arquivo. O shell tenta expandir a palavra que contém esse caractere * para a lista de nomes de arquivos que correspondem ao padrão.

Portanto, se /path/to/backup/files contiver arquivos a.gz e b.gz , o shell realmente chamará rm com 3 argumentos: rm , /path/to/backup/files/a.gz e /path/to/backup/files/b.gz , que parece mais com o que você deseja aqui .

Observe que $OUTPUT em si ainda precisa ser citado, caso contrário, pode acabar sendo dividido se contiver caracteres $IFS ou também estar sujeito a globbing se contiver qualquer caractere curinga (como * acima) .

Também é uma boa ideia habituar-se a escrever:

rm -- "$OUTPUT"/*.gz

Aqui $OUTPUT começa com / , portanto, tudo bem, mas no dia em que você alterar $OUTPUT para -foo- , por exemplo, ele deixará de funcionar quando -foo-/... for usado por rm como opções.

Se o script não for interativo, talvez você queira adicionar a opção -f a rm . Isso desativará todos os prompts do usuário e removerá o erro se não houver nenhum arquivo correspondente (a maioria dos shells, quando um glob não tiver correspondência, passará o padrão como está para o aplicativo e rm -f não reclamará quando solicitado a remover um arquivo que não existe em primeiro lugar).

    
por 28.11.2016 / 16:28
-2

Tente obter esses arquivos e exclua-os:

ARCS='ls $OUTPUT | grep "\.gz$"'

for _arch in $ARCS; do
    rm -f $_arch
done
    
por 28.11.2016 / 15:49