Remove o arquivo, mas somente se for um symlink

9

Idealmente, gostaria de um comando como este

rm --only-if-symlink link-to-file

porque eu me queimei muitas vezes acidentalmente excluindo o arquivo em vez do link simbólico apontando para o arquivo. Isso pode ser especialmente ruim quando o sudo está envolvido. Agora, claro, faço um ls -al para ter certeza de que é realmente um link simbólico e tal, mas que é vulnerável a erros de operador (nome semelhante a arquivo, erro de digitação, etc) e condições de corrida (se alguém quiser que eu exclua um arquivo por algum motivo) . Existe alguma maneira de verificar se um arquivo é um link simbólico e excluí-lo apenas se ele estiver em um comando?

    
por Shelvacu 20.03.2016 / 22:23

3 respostas

18
 $ rm_if_link(){ [ ! -L "$1" ] || rm -v "$1"; }

 #test
 $ touch nonlink; ln -s link
 $ rm_if_link nonlink
 $ rm_if_link link
   removed 'link'     
    
por 20.03.2016 / 22:37
5

Você pode usar find e sua condição de teste -type l (que testa para ver se o objeto encontrado é uma tinta l ou não)

Por exemplo, se você tiver um arquivo chamado foo no diretório atual, poderá fazer isso:

$ find . -type l -iname "foo" -delete

Você pode simplificar isso com apenas:

$ find . -maxdepth 1 -type l -delete

O que excluiria todos os links simbólicos no diretório atual.

Aviso:

A opção -delete em find é realmente muito perigosa. Certifique-se de colocá-lo no final do comando FIND. Se você errar, ele excluirá tudo o que encontrar, independentemente de os resultados corresponderem ao seu condicional.

Como sugerido nos comentários, uma opção mais segura pode ser usar find e rm -i (o que obriga a confirmar a remoção do arquivo) em conjunto:

$ $ find . -type l -iname "foo" | xargs rm -i

Pessoalmente, uso -exec trash {} \; para excluir arquivos temporariamente, porque eu, como você, já foi gravado por rm no passado. O dobro vale para um sinalizador -delete em extravio.

link

    
por 20.03.2016 / 22:30
4
zsh -c 'rm foo(@)'

@ é um qualificador da glob ; o padrão foo(@) corresponde ao que foo corresponde, mas apenas aos links simbólicos.

foo(-@) corresponderia apenas a links simbólicos quebrados. foo(@,L0) corresponderia apenas a links simbólicos e arquivos vazios.

É claro que, se você estiver executando o zsh, basta digitar rm foo(@) . Você precisa tomar cuidado para não pressionar Enter antes de digitar (@) .

    
por 20.03.2016 / 22:41