Quiero poner un comando en un script de shell que creará un enlace simbólico al directorio, pero este script podría ejecutarse una y otra vez, por lo que en las invocaciones posteriores, el comando no debería cambiar nada.
Aquí está la estructura del directorio:
% tree /tmp/test_symlink
/tmp/test_symlink
├── foo
└── repo
└── resources
└── snippets
├── php.snippets
├── sh.snippets
├── snippets.snippets
├── sql.snippets
└── vim.snippets
Quiero crear un enlace simbólico en foo/
fragmentos llamados que apunta al directorio /tmp/test_symlink/repo/resources/snippets
.
Entonces 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'
lo que da el resultado deseado.
% 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 directorios, 5 archivos
Sin embargo, cuando el comando se ejecuta nuevamente,
% 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'
crea un enlace simbólico a un directorio, donde el enlace simbólico ya existe coloca el enlace simbólico dentro del directorio 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 qué sucede esto y cómo puedo modificar el comando para que invocaciones posteriores no creen este efecto extraño?
fuente
-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
¿crees que es mejor tratar un enlace simbólico como un archivo siempre? ¿Pensé que sería mejor limitar el uso de estas opciones "especiales"?-T
es como lo hacesln
idempotente. Hay otras formas de obtener el mismo resultado si lo prefiere, como eliminar el enlace y volver a crearlo, o si ya sabe quefoo
existeln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/
(en realidad, esa podría ser una mejor respuesta, lo actualizaré).if
declaraciones para detectar la presencia del enlace simbólico y omitir el comando si el enlace simbólico existía, pero los scripts terminan abarrotados y son difíciles de leer, estaba buscando algo idempotente pero simple, comomkdir -p
no usar pruebas , no es lógico, solo un buen revestimiento :)-T
, pero el final de mi respuesta presenta otra solución que no utiliza-T
.Lo mejor que puedo decir es que en la segunda pasada, el
ln
comando se comporta comocp
omv
, y es que si ve un "directorio" en <destination>, colocará el archivo dentro, de lo contrario si <destination> no existe, hará <destination>. (que es lo que evita el truco "slashdot", es decir, se asegurará de que <destination> exista y sea un directorio).Pero podría estar equivocado.
En cualquier caso, esto parece funcionar
fuente