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

0

Eu tenho um monte de usuários indisciplinados com contas de email em um servidor meu. Eles nunca esvaziam sua lixeira ou 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 eu quero apagar;
  2. crie um script que leia linha por linha, todo diretório e apague tudo, 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 seus conteúdos.

Então eu tenho esse script:

#!/bin/bash 

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

Quando executo o script, recebo o seguinte erro:

ls: não pode acessar ~/mail/[email protected]/.Junk/new/: Não   tal arquivo ou diretório

para todos os diretórios, mas se eu digitar

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

Funciona bem.

porque?

SpaceDog
fonte
Chron executa seu script em root, então ~ aponta para um diretório home diferente (provavelmente /root ). use caminhos completos e garanta que o root tenha acesso às pastas e ao conteúdo.
Frank Thomas
Você executa o script (ou cron) com o mesmo usuário daquele ao fazer o "ls" manualmente? Tente ecoar ~ caminho no script para ver se você está no lugar certo e talvez você precise usar o caminho absoluto de sua casa em vez do ~
Flinth

Respostas:

3

Cite suas variáveis!

while read line e então fazendo ls $line não funciona; você tem que usar ls "$line" para lidar com espaços em branco nas variáveis. Geralmente, cite suas variáveis ​​quando você as usa!

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

~/mail/. Trash/new

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

  • ~/mail
  • Trash/new

No pior dos casos, se você fez 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 manipular corretamente os espaços em branco é explicado aqui :

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

o -r impede que barras invertidas sejam expandidas e IFS= ajuda no caso em que uma linha começa ou termina com um espaço em branco, que a casca poderia cortar 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, vai começar a partir /roote não da casa do usuário no ponto de criação do arquivo de texto.

Portanto, armazene os caminhos completos em seu arquivo.

slhck
fonte