Algum sistema operacional fornece um mecanismo (chamada do sistema - não programa de linha de comando) para alterar o nome do caminho referenciado por um link simbólico (link simbólico) - além de desvincular o antigo e criar um novo?
O padrão POSIX não. O Solaris 10 não. O MacOS X 10.5 (Leopard) não. (Estou toleravelmente certo de que nem o AIX nem o HP-UX também. A julgar pela lista de chamadas do sistema Linux, o Linux também não possui essa chamada.)
Existe alguma coisa que faz?
(Espero que a resposta seja "Não".)
Como provar que é negativo é difícil, vamos reorganizar a questão.
Se você souber que algum sistema operacional (semelhante ao Unix) ainda não listado não possui nenhuma chamada de sistema para reescrever o valor de um link simbólico (a string retornada por readlink()
) sem remover o link simbólico antigo e criar um novo, adicione-o - ou eles - em uma resposta.
ln
comando (ou a API equiavalente) substituindo o link antigo? Qual problema você está tendo?Respostas:
AFAIK, não, você não pode. Você precisa removê-lo e recriá-lo.Na verdade, você pode sobrescrever um link simbólico e, assim, atualizar o nome do caminho mencionado por ele:EDIT : Como o OP apontou em um comentário, o uso da
--force
opção faráln
uma chamada de sistema paraunlink()
antessymlink()
. Abaixo, a saída dastrace
minha caixa linux provando:Então eu acho que a resposta final é "não".EDIT : O seguinte é copiado da resposta de Arto Bendiken em unix.stackexchange.com, por volta de 2016.
Na verdade, isso pode ser feito atomicamente
rename(2)
, criando primeiro o novo link simbólico com um nome temporário e depois substituindo de maneira limpa o link simbólico antigo de uma só vez. Como a página do manual afirma:No shell, você faria isso da
mv -T
seguinte maneira:Você pode
strace
executar esse último comando para garantir que ele esteja realmente sendo usado porrename(2)
baixo do capô:Observe que, acima, ambos
mv -T
estrace
são específicos do Linux.No FreeBSD, use
mv -h
alternadamente.Nota do editor: É assim que Capistrano faz isso há anos, desde ~ 2.15. Veja esta solicitação de recebimento .
fonte
Sim você pode!
fonte
-f
opção significa 'remover o destino existente' antes de criar o novo. Portanto, esse comando alcança o resultado, masunlink(2)
seguindo seguido porsymlink(2)
. Não era disso que se tratava a pergunta original. Observe também que a resposta aceita e a próxima resposta mais votada usamln -sf
para fazer o trabalho, mas, comostrace
mostra a saída, simunlink()
esymlink()
porque não há uma chamada de sistema para modificar um link simbólico.Não é necessário desvincular explicitamente o link simbólico antigo. Você consegue fazer isso:
(ou use o link simbólico equivalente e renomeie as chamadas). Isso é melhor do que desvincular explicitamente porque a renomeação é atômica, portanto, você pode ter certeza de que o link sempre apontará para o destino antigo ou novo. No entanto, isso não reutilizará o inode original.
Em alguns sistemas de arquivos, o destino do link simbólico é armazenado no próprio inode (no lugar da lista de bloqueios), se for curto o suficiente; isso é determinado no momento em que é criado.
Com relação à afirmação de que o proprietário e o grupo são irrelevantes, o link simbólico (7) no Linux diz que há um caso em que é significativo:
fonte
set -x -e; mkdir junk; ( cd junk; mkdir olddir newdir; ln -s olddir mylink; ls -ilR; ln -s newdir temp; ls -ilR; mv temp mylink; ls -ilR; ); rm -fr junk
. Se você criar arquivos oldfile e newfile em vez de diretórios e executar o script equivalente (principalmente alterando olddir para oldfile, newdir para newfile), obterá o efeito esperado. Apenas uma complexidade extra! Obrigado pela resposta.Apenas um aviso para as respostas corretas acima:
O uso do método -f / --force oferece risco de perda do arquivo se você misturar origem e destino:
Claro que isso é intencional, mas geralmente ocorrem erros. Portanto, excluir e recriar o link simbólico é um pouco mais trabalhoso, mas também um pouco mais econômico:
que pelo menos mantém meu arquivo.
fonte
-f
ou--force
é sempre um pouco perigoso; presume que o usuário saiba do que se trata. É duplamente letal se você usá-lo habitualmente (rm -fr …
toda vez que é perigoso).Não desvinculá-lo e criar o novo faria a mesma coisa no final?
fonte
ln --force
comando substituirá absolutamente um link existente.ln (1)
, enquanto mate b. está discutindo o fato de quesymlink (2)
se não apoiar a substituição. Vocês dois estão certos, e eu sugeriria que analisar a implementaçãoln (1)
daria a maneira mais idiomática de realizar o procedimento de desassociação / desassociação.Caso isso ajude: existe uma maneira de editar um link simbólico com o comandante da meia-noite (mc). O comando do menu é (em francês na minha interface mc):
que pode ser traduzido para:
O atalho é Cx Cs
Talvez ele use internamente o
ln --force
comando, não sei.Agora, estou tentando encontrar uma maneira de editar vários links simbólicos de uma só vez (foi assim que cheguei aqui).
fonte
unlink()
seguido de umsymlink()
, simplesmente porque é isso que os sistemas semelhantes ao Unix fornecem.Tecnicamente, não há comando interno para editar um link simbólico existente. Pode ser facilmente alcançado com alguns comandos curtos.
Aqui está uma pequena função bash / zsh que escrevi para atualizar um link simbólico existente:
fonte
unlink()
esymlink()
com o novo valor, que é o que acontece nos bastidores com seu código. Pessoalmente, eu teria a função insistir em exatamente dois (ou talvez um múltiplo de dois) argumentos e fiança se a invocação não estivesse correta. Essa é uma perspectiva particular, no entanto.