Script de shell 'rm -r': redireciona o prompt protegido contra gravação e responde “n”

2

Eu tenho algumas linhas em um script de shell cuja função é percorrer diretórios, combinar alguns nomes e excluí-los. Algumas áreas do sistema de arquivos são protegidas contra gravação e gostaria de deixá-las em paz, mas redirecionar o prompt ou alguma outra indicação do erro para um log quando elas forem encontradas.

Usar rm -r /path/to/directory nesse ponto do script faz com que o script seja enviado

rm: descend into write-protected directory /path/to/directory/subdirectory?

Então, ele trava e [eventualmente] atinge o tempo limite quando é deixado em seus próprios dispositivos.

Eu tentei corrigir esse comportamento colocando o "n" nesse prompt com

yes n | rm -rv /path/to/directory

Isso produz dois resultados indesejados:

  1. Saída de yes: standard output: Broken pipe; yes: write error para cada diretório removido e
  2. Não retornando a mensagem rm: descend into write-protected... para stdout.

Qual é o caminho certo para fazer isso?

Atualização: De acordo com @roaima, eu não estou realmente direcionando yes n para o prompt porque a existência desse pipe torna rm não-interativo. Isso é irônico porque eu estava realmente explorando a interatividade apenas para obter alguma saída, mas se eu desligar a interatividade, o programa simplesmente sairia errado. Eu não quero ignorar o erro (por exemplo, adicionando || true como eu vi tantos outros lugares no SE) porque eu quero os nomes dos arquivos protegidos.

    
por WAF 03.03.2015 / 20:23

3 respostas

2

Eu sugiro considerar uma ferramenta diferente. O comando 'find' é muito poderoso e depois de passar algumas das regras de sintaxe, é fácil de usar.

Exemplo:

find /directory -name pattern -perm g=w -exec /bin/rm {} \;

Isto irá procurar por todos os arquivos e subpastas sob / directory que tenham a permissão de grupo de 'write' (coincidir com a lógica para 0020 octal chmod format). Ele então apagará esse arquivo.

Ou você pode executá-lo com a opção de impressão e obter uma lista de quais arquivos correspondem ao padrão de localização.

ex: find /directory -name pattern -perm 0111 -print
    
por 03.03.2015 / 20:37
1

rm pedirá confirmação para destinos não graváveis se stdin for um terminal. O sinal -i , por outro lado, ativa a confirmação de todos os destinos . Claramente nem funciona com a solução simples de canalizar yes n para rm , então devemos usar outra coisa.

Usando o GNU find, exclua todos os objetos que tenham pelo menos um dos bits do modo de gravação definidos (como de costume, use -print em vez de -delete no primeiro teste):

find dir/ -perm /0222 -delete

Ou, exclua todos os arquivos (*) com pelo menos um conjunto de bits no modo de gravação, mas pule o conteúdo de diretórios não graváveis:

find . -type d ! -perm /0222 -prune -o ! -type d -perm /0222 -exec rm {} + 

(* na verdade tudo exceto diretórios)

-delete implica em uma busca em profundidade (pelo menos no GNU find), e não funciona com -prune , então não podemos usar isso aqui. Podemos excluir diretórios graváveis vazios depois disso:

find . -type d -perm /0222 -delete

Isso lançará erros para diretórios não vazios.

-perm /0222 significa "qualquer um dos bits de gravação está definido" e seu inverso ! -perm /0222 para "nenhum dos bits de gravação está definido".

Em outras versões do find, use +0222 em vez de /0222 . (De acordo com a manpage do GNU, o primeiro entra em conflito com os requisitos do POSIX e foi descontinuado.)

Para encontrar os arquivos e diretórios não-graváveis, podemos usar da mesma forma

find . ! -perm /0222 

Listar recursivamente o conteúdo de diretórios não-graváveis é um pouco mais difícil de fazer, mas com ferramentas GNU isso pode funcionar:

find . ! -perm /0222 -print0 | xargs -0 find 
    
por 04.04.2017 / 21:29
-2

Primeiro, altere a permissão do diretório que você deseja excluir usando o comando:

chmod -R 777 directory/ 

e, em seguida, remova o diretório usando o comando:

rm -rf directory/.
    
por 10.08.2016 / 08:03