Quero colocar um comando em um script de shell que criará um link simbólico para o diretório, mas esse script pode ser executado repetidamente, portanto, nas invocações subsequentes, o comando não deve alterar nada.
Aqui está a estrutura de diretórios:
% tree /tmp/test_symlink
/tmp/test_symlink
├── foo
└── repo
└── resources
└── snippets
├── php.snippets
├── sh.snippets
├── snippets.snippets
├── sql.snippets
└── vim.snippets
Eu quero criar um link simbólico foo/
chamado snippets que aponta para o diretório /tmp/test_symlink/repo/resources/snippets
.
Então eu corro:
% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets' -> '/tmp/test_symlink/repo/resources/snippets'
qual dá o resultado desejado.
% tree /tmp/test_symlink
/tmp/test_symlink
├── foo
│ └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
└── resources
└── snippets
├── php.snippets
├── sh.snippets
├── snippets.snippets
├── sql.snippets
└── vim.snippets
5 diretórios, 5 arquivos
No entanto, quando o comando é executado novamente,
% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets/snippets' -> '/tmp/test_symlink/repo/resources/snippets'
ele cria um link simbólico para um diretório, onde o link simbólico já existe coloca o link simbólico dentro do diretório real
% tree /tmp/test_symlink
/tmp/test_symlink
├── foo
│ └── snippets -> /tmp/test_symlink/repo/resources/snippets
└── repo
└── resources
└── snippets
├── php.snippets
├── sh.snippets
├── snippets -> /tmp/test_symlink/repo/resources/snippets
├── snippets.snippets
├── sql.snippets
└── vim.snippets
por que isso está acontecendo e como posso modificar o comando para que invocações subsequentes não criem esse efeito estranho?
fonte
-n, --no-dereference treat LINK_NAME as a normal file if it is a symbolic link to a directory
.-T, --no-target-directory treat LINK_NAME as a normal file always
você acha que é melhor tratar sempre um link simbólico como um arquivo? Eu teria pensado que seria melhor limitar o uso dessas opções "especiais"?-T
é assim que você faz oln
idempotente. Existem outras maneiras de obter o mesmo resultado, se você preferir, como excluir o link e recriá-lo, ou se vocêfoo
já existe,ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/
(na verdade essa pode ser uma resposta melhor, atualizarei).if
instruções para detectar a presença do link simbólico e pular o comando, se o link simbólico existisse, mas os scripts acabam ficando confusos e difíceis de ler, eu estava procurando por algo idempotente, mas simples, comomkdir -p
não usar testes , nenhuma lógica, bom apenas ol forros :)-T
, mas o final da minha resposta apresenta outra solução que não usa-T
.O melhor que posso dizer aqui é que, na segunda passagem, o
ln
comando se comporta comocp
oumv
, ou seja, se ele vir um "diretório" em <destination>, ele colocará o arquivo dentro dele, caso contrário, se <destination> não existir, ele fará <destino>. (que é o que o truque "slashdot" evita - isto é, garantirá que o <destino> exista e seja um diretório).Mas eu posso estar errado.
Em ambos os casos, isso parece funcionar
fonte