Pode acessar diretórios usando ls, mas não de Bash

0

Eu tenho um monte de usuários indisciplinados com contas de e-mail em um servidor meu. Eles nunca esvaziam a lixeira ou as pastas de lixo eletrônico e o número de arquivos sobe até o infinito.

Estou criando um script Bash para apagar esses arquivos periodicamente usando o cron.

Eu fiz isso:

  1. crie um arquivo txt com uma lista de diretórios que desejo excluir;
  2. crie um script que leia linha por linha, cada diretório e exclua tudo de cur e new .

Exemplo de arquivo txt:

~/mail/.Junk/cur
~/mail/.Junk/new
~/mail/.Trash/cur
~/mail/. Trash/new
~/mail/[email protected]/.Junk/cur
~/mail/[email protected]/.Junk/new
~/mail/[email protected]/.Trash/cur
~/mail/[email protected]/.Trash/new
~/mail/[email protected]/.Junk/cur
~/mail/. [email protected]/.Junk/new
~/mail/. [email protected]/.Trash/cur
~/mail/. [email protected]/.Trash/new

Estou na primeira fase da criação do script, onde testo se consigo acessar os diretórios e listar seu conteúdo.

Então eu tenho este script:

#!/bin/bash 

while read line 
do 
ls $line
done < ~/directories.txt 

Quando executo o script, recebo o seguinte erro:

ls: cannot access ~/mail/[email protected]/.Junk/new/: No such file or directory

para todos os diretórios, mas se eu digitar

ls ~/mail/[email protected]/.Junk/new/

funciona bem.

por quê?

    
por SpaceDog 29.06.2018 / 16:35

1 resposta

3

Cite suas variáveis!

while read line e, em seguida, ls $line não funcionarão; você tem que usar ls "$line" para manipular espaços em branco nas variáveis. Geralmente, cite suas variáveis quando você as usa!

Se você não fizer isso, estará fazendo um grande problema ao tentar rm $line , se essa linha for

~/mail/. Trash/new

Então, se você fez ls $line , tentaria listar duas pastas:

  • ~/mail
  • Trash/new

No pior caso, se você fizesse um rm -rf $line , você removeria ~/mail completamente ! Então, use ls "$line" dentro do seu loop. E o mesmo para rm .

Na verdade, a maneira mais robusta de ler um arquivo linha por linha e tratar adequadamente os espaços em branco é explicada aqui :

while IFS= read -r line; do
    ls "$line"
done < "$file"

O -r impede que as barras invertidas sejam expandidas, e IFS= ajuda no caso de uma linha começar ou terminar com um espaço em branco, que o shell cortaria de outra forma.

Não use caminhos que precisam ser expandidos!

Se o seu arquivo de texto contiver caminhos que serão posteriormente expandidos, o caminho será alterado dependendo de quem executa o script. Aqui, ~ será expandido para o caminho inicial do usuário no momento da execução, portanto, se você estiver executando o script como root , ele será iniciado a partir de /root e não a partir da origem do usuário no ponto de criação o arquivo de texto.

Portanto, armazene os caminhos completos em seu arquivo.

    
por 29.06.2018 / 16:57

Tags