Idealmente, eu gostaria de um comando como este
rm --only-if-symlink link-to-file
porque eu me queimei muitas vezes excluindo acidentalmente 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 garantir que seja realmente um link simbólico e tal, mas isso é vulnerável a erros do operador (arquivo com nome semelhante, 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 estiver em um comando?
bash
command-line
rm
Shelvacu
fonte
fonte
Respostas:
fonte
!
e mudar||
para&&
||
formulário.&&
derruba as coisas se você estiver noset -e
modo.[ ! -L $1 ]
), usando um operador inválido ([ ! -l foo ]
) ou mesmo erro de sintaxe ([ ! -q foo || echo foo
)rm_if_link(){ [ -L "$1" ] && rm -v "$1"; }
é que executá-lo em umset -e
modo não vinculado matará seu processo de shell. Você pode acrescentar,|| :
mas, então, torna-se, IMHO, ainda menos claro que a! ||
versão, e impedirá que umarm
falha o mateset -e
, o que provavelmente é indesejável.! ||
é bastante conciso e claro, e não sofre de nenhum desses problemas.rm
dentro de seu teste, b) use uma declaração if real, c) não saia usando-e
shells interativos internos (e teste seus scripts!). Se você quiser discutir sobre legibilidade, usarif
para testar se algo é um link é claramente o vencedor.Você pode usar
find
e sua-type l
condição de teste (que testa para verificar 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 o seguinte:Você pode simplificar isso com apenas:
O que excluiria todos os links simbólicos no diretório atual.
Atenção:
A
-delete
opçãofind
é realmente muito perigosa. Certifique-se de colocá-lo no final do comando FIND. Se você o colocar incorretamente, ele excluirá tudo o que encontrar, independentemente de os resultados corresponderem ao seu condicional.Conforme sugerido nos comentários, uma opção mais segura pode ser usar
find
erm -i
(o que força você a confirmar a remoção do arquivo) em conjunto:Pessoalmente, uso
-exec trash {} \;
para excluir arquivos temporariamente, porque, como você, já foram queimadosrm
no passado. Double vai para uma-delete
bandeira mal colocada .http://slackermedia.ml/trashy
fonte
find . -type l -iname "foo" | xargs rm -i
é mais seguro.rm -i
Por segurança, com certeza.-print0
parafind
e-0
paraxargs
.@
é um qualificador glob ; o padrãofoo(@)
corresponde ao quefoo
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.Obviamente, se você estiver executando o zsh, basta digitar
rm foo(@)
. Você precisa tomar cuidado para não pressionar Enterantes de digitar(@)
.fonte