rm opção para falhar em arquivos inexistentes

4

A página man de rm no GNU coreutils 8.12.197-032bb descreve a opção -f ou --force como "ignorar arquivos inexistentes, nunca solicitar". Sem essa opção, ele removerá todos os arquivos existentes, nunca solicitará e retornará um código de saída diferente de zero se algum dos arquivos especificados não existir. Eu gostaria de preservar os arquivos se qualquer dos arquivos especificados não existirem . Qual é a maneira mais fácil de fazer isso?

O caso de uso é segurança : Se eu estou tentando remover um arquivo que não existe, pode ser porque há uma expectativa inválida (ou bug simples) no comando. Por exemplo, o famoso rm -rf /usr /lib/nvidia-current/xorg/xorg poderia ter sido evitado de várias maneiras, sendo uma delas uma dessas opções (obviamente, a menos que o usuário por alguma incrível coincidência tivesse um diretório /lib/nvidia-current/xorg/xorg ), e outra sendo para Use More Quotes ™ . No entanto, as citações nem sempre são suficientes. Por exemplo, considere ssh host '/bin/rm some paths; /bin/bash foo.sh' - Se eu tivesse esquecido o ponto-e-vírgula ou inserido praticamente qualquer outro símbolo, como cólon ou vírgula, ele teria tentado remover /bin/bash e ~/foo.sh .

    
por l0b0 08.10.2012 / 15:13

3 respostas

1

Eu uso esse tipo de coisa:

mkdir DELETE && mv "some" "paths" DELETE && rm -rf DELETE

Para um único caminho:

mv /some/path DELETE && rm -rf DELETE

Melhor ainda, digite o rm command em uma linha de comando separada: mv /some/path DELETE Digite rm -rf DELETE Digite . Dessa forma, o único comando rm que faz parte do histórico do shell está em um arquivo chamado DELETE , portanto, se você removeu uma versão antiga de um arquivo, não corre o risco de remover a nova versão pressionando acidentalmente Up o número errado de vezes então Enter .

Se você quiser automatizar um pouco:

mv_to_DELETE () {
  mkdir DELETE &&
  mv -- "$@" DELETE/
}
mv_to_DELETE "some" "paths"
rm -rf DELETE
    
por 09.10.2012 / 01:56
1

Algo como

paths=("some" "paths")
for path in "${paths[@]}"
do
    [ -e "$path" ] || exit 1
done

antes de cada comando rm ser muito mais complicado para um iniciante, e depende dos arrays Bash.

    
por 08.10.2012 / 15:14
0
for path in "some" "paths"
do
    [ -e "$path" ] || exit 1
done

é mais portável, mas significa duplicar a lista de caminhos no loop e o comando rm . E o armazenamento de todos os caminhos na mesma variável de string significa que o script não suporta mais nenhum dos caracteres IFS nos nomes de arquivos.

    
por 08.10.2012 / 15:16

Tags