$ rm_if_link(){ [ ! -L "$1" ] || rm -v "$1"; }
#test
$ touch nonlink; ln -s link
$ rm_if_link nonlink
$ rm_if_link link
removed 'link'
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?
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.
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 (@)
.
Tags command-line bash rm