Chcę wstawić polecenie do skryptu powłoki, który utworzy dowiązanie symboliczne do katalogu, ale ten skrypt może być uruchamiany w kółko, więc przy kolejnych wywołaniach polecenie nie powinno niczego zmieniać.
Oto struktura katalogów:
% tree /tmp/test_symlink
/tmp/test_symlink
├── foo
└── repo
└── resources
└── snippets
├── php.snippets
├── sh.snippets
├── snippets.snippets
├── sql.snippets
└── vim.snippets
Chcę utworzyć dowiązanie symboliczne w foo/
nazwanych fragmentach, które wskazują katalog /tmp/test_symlink/repo/resources/snippets
.
Więc biegam:
% ln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/snippets
'/tmp/test_symlink/foo/snippets' -> '/tmp/test_symlink/repo/resources/snippets'
co daje pożądany rezultat.
% 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 katalogów, 5 plików
Jednak po ponownym uruchomieniu polecenia
% 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'
tworzy symlink do katalogu, w którym istnieje symlink, umieszcza symlink w prawdziwym katalogu
% 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
dlaczego tak się dzieje i jak mogę zmodyfikować polecenie, aby kolejne wywołania nie wywołały tak dziwnego efektu?
źródło
-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
czy uważasz, że lepiej zawsze traktować dowiązanie symboliczne jako plik? Myślałbym, że lepiej byłoby ograniczyć korzystanie z tych „specjalnych” opcji?-T
jakln
czynisz idempotentny. Istnieją inne sposoby uzyskania tego samego wyniku, jeśli wolisz, takie jak usunięcie linku i ponowne utworzenie go, lub jeśli wiesz, żefoo
już istniejeln -sfv /tmp/test_symlink/repo/resources/snippets /tmp/test_symlink/foo/
(faktycznie może to być lepsza odpowiedź, zaktualizuję).if
instrukcji do wykrywania obecności dowiązania symbolicznego i pomijałem polecenie, jeśli dowiązanie symboliczne istniało, ale skrypty stają się zagracone i trudne do odczytania, szukałem czegoś idempotentnego, ale prostego, jakmkdir -p
brak testów , bez logiki, po prostu dobre-T
, ale koniec mojej odpowiedzi przedstawia inne rozwiązanie, z którego nie korzystam-T
.Najlepsze, co mogę powiedzieć, to, co się tutaj dzieje, to że przy drugim przejściu
ln
polecenie zachowuje się tak,cp
lubmv
jeśli widzi „katalog” w <cel>, umieści w nim plik, w przeciwnym razie, jeśli <cel> nie istnieje, spowoduje <destination>. (czego unika sztuczka „slashdot” - tzn. upewni się, że <cel> istnieje i jest katalogiem).Ale mogę się mylić.
W obu przypadkach wydaje się, że to działa
źródło