Je veux mettre une commande dans un script shell qui créera un lien symbolique vers le répertoire, mais ce script pourrait être exécuté encore et encore, donc lors des appels ultérieurs, la commande ne devrait rien changer.
Voici la structure du répertoire:
% tree /tmp/test_symlink
/tmp/test_symlink
├── foo
└── repo
└── resources
└── snippets
├── php.snippets
├── sh.snippets
├── snippets.snippets
├── sql.snippets
└── vim.snippets
Je veux créer un lien symbolique dans des foo/
extraits appelés qui pointe vers le répertoire /tmp/test_symlink/repo/resources/snippets
.
Je lance donc:
% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets' -> '/tmp/test_symlink/repo/resources/snippets'
ce qui donne le résultat souhaité.
% 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 répertoires, 5 fichiers
Cependant, lorsque la commande est réexécutée,
% 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'
il crée un lien symbolique vers un répertoire, où le lien symbolique existe déjà met le lien symbolique à l'intérieur du répertoire réel
% 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
pourquoi cela se produit-il et comment puis-je modifier la commande afin que les invocations suivantes ne créent pas cet effet étrange?
la source
-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
pensez-vous qu'il est préférable de toujours traiter un lien symbolique comme un fichier? J'aurais pensé qu'il valait mieux limiter l'utilisation de ces options "spéciales"?-T
c'est comment vous faitesln
idempotent. Il existe d'autres façons d'obtenir le même résultat si vous préférez, comme la suppression du lien et sa recréation, ou si vous savez qu'ilfoo
existe déjàln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/
(en fait, cela pourrait être une meilleure réponse, je mettrai à jour).if
instructions pour détecter la présence du lien symbolique et ignorer la commande si le lien symbolique existait, mais les scripts finissent par être encombrés et difficiles à lire, j'allais vers quelque chose d'idempotent mais simple, comme n'utilisermkdir -p
aucun test , pas de logique, juste de bons ol one liners :)-T
, mais la fin de ma réponse présente une autre solution qui n'utilise pas-T
.Le mieux que je puisse dire, c'est que lors de la deuxième passe, la
ln
commande se comporte commecp
oumv
, ce qui signifie que si elle voit un "répertoire" à <destination>, elle y mettra le fichier, sinon si <destination> ne le fait pas existe, il fera <destination>. (c'est ce que l'astuce "slashdot" évite - c'est-à-dire qu'il s'assurera que la <destination> existe et est un répertoire).Mais je peux me tromper.
Dans les deux cas, cela semble fonctionner
la source