Utwórz symboliczne łącze do względnej nazwy ścieżki

64

Mogę to zrobić:

$ pwd
/home/beau
$ ln -s /home/beau/foo/bar.txt /home/beau/bar.txt
$ readlink -f bar.txt
/home/beau/foo/bar.txt

Ale chciałbym móc to zrobić:

$ pwd
/home/beau
$ cd foo
$ ln -s bar.txt /home/beau/bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

czy to możliwe? Czy mogę jakoś rozwiązać względną nazwę ścieżki i przekazać ją ln?

Humphrey Bogart
źródło
Ale jaki jest problem, który zostałby rozwiązany za pomocą opisanego zachowania?
forcefsck
Powiedzmy, że oferujesz skompresowany folder do pobrania i chciałbyś przekazać instrukcje, które można wkleić do kopiowania, jak symlinkować niektóre pliki tego folderu.
Humphrey Bogart
2
ln -s $(pwd)/bar.txt ~/lub dołącz skrypt instalacyjny.
forcefsck
2
link przechowuje nazwę, której używasz w wierszu poleceń. Rozdzielczość tej nazwy do pliku jest wykonywana względem lokalizacji łącza. Musisz użyćln -s foo/bar.txt /home/beau/bar.txt
pqnet

Odpowiedzi:

62

Jeśli utworzysz dowiązanie symboliczne do ścieżki względnej, zostanie ono zapisane jako względne dowiązanie symboliczne, a nie bezwzględne, jak pokazano w przykładzie. To na ogół dobra rzecz. Absolutne dowiązania symboliczne nie działają, gdy system plików jest montowany gdzie indziej.

Twój przykład nie działa, ponieważ jest względny do katalogu nadrzędnego dowiązania symbolicznego, a nie gdzie lnjest uruchamiany.

Możesz to zrobić:

$ pwd
/home/beau
$ ln -s foo/bar.txt bar.txt
$ readlink -f /home/beau/bar.txt
/home/beau/foo/bar.txt

Lub w tym przypadku:

$ cd foo
$ ln -s foo/bar.txt ../bar.txt

Ważne jest, aby zdać sobie sprawę, że pierwszy argument po ln -sjest przechowywany jako cel dowiązania symbolicznego. Może to być dowolny dowolny ciąg (z tym, że nie może być pusty i nie może zawierać znaku NUL), ale w momencie używania i rozwiązywania dowiązania symbolicznego ciąg ten jest rozumiany jako ścieżka względna do katalog nadrzędny dowiązania symbolicznego (gdy się nie zaczyna /).

penguin359
źródło
2
Ładnie powiedziane. Odpowiedziałeś na to, pisząc własną odpowiedź. :)
Shadur
Właśnie miałem nieco inne pytanie - i to doskonale na nie odpowiada. Chciałem wiedzieć, jak odwoływać się do katalogu domowego w dowiązaniu symbolicznym, aby działało, gdy przeniosłem go z jednego użytkownika na drugiego. Nie byłem pewien, czy coś ~będzie działać.
Joe
„ten ciąg znaków jest rozumiany jako ścieżka względna do katalogu nadrzędnego dowiązania symbolicznego” - to wyjaśnia wszystko!
Bojan Komazec
24

Jeśli używasz nowszych coreutils (używam coreutils-8.22-11), masz do tego opcję:

ln --help | grep relative

może przechowywać dowolny tekst; jeśli później rozwiązany, względny link to -r, --relative tworzy dowiązania symboliczne względem lokalizacji łącza

Na przykład:

$ mkdir /tmp/test
$ touch /tmp/test/to
$ ln -rs /tmp/test/to /tmp/test/from
$ ls -l /tmp/test/from
    lrwxrwxrwx 1 ptr ptr 4 aug   25 17.02 /tmp/test/to -> from
ptr
źródło
Hm, dla mnie wydaje się, że nie ma takiej opcji -r. Używam Maca.
ivkremer
1
@ivkremer wydaje się, że ta opcja jest dostępna od coreutils> = 8.16 (źródło: superuser.com/a/837935/403979 )
DJCrashdummy
Wydaje się, że użycie flagi względnej rozwiązało problem „zbyt wielu poziomów dowiązań symbolicznych”, których doświadczałem.
Vix,
12

Przepraszam, nie. Łącza symboliczne odnoszą się do lokalizacji, w której znajduje się łącze, a nie do lokalizacji, w której byłeś podczas tworzenia łącza. Istnieje kilka dobrych powodów takiego zachowania, z których większość polega na montowaniu zdalnych systemów plików.

Shadur
źródło
7

Istnieje wygodne małe narzędzie o nazwie symlinks(pierwotnie Mark Lords, obecnie utrzymywane przez J. Brandta Buckleya), obecne w wielu dystrybucjach Linuksa.

Aby przekonwertować wszystkie bezwzględne dowiązania symboliczne w katalogu na względne:

symlinks -c /path/to/directory

Niestety nie ma opcji, aby przekonwertować pojedynczy link, musisz najpierw przenieść go do własnego katalogu.

mkdir ../tmp
mv link-to-relativize ../tmp
symlinks ../tmp
mv ../tmp/* .
rmdir ../tmp
Gilles
źródło
dzięki. dowiązania symboliczne dostępne na github . Utrzymywany przez J. Brandta Buckleya. wersja 1.4.3 .
Evgeny Vereshchagin
3

Możesz spróbować:

ln -s `pwd`/bar.txt /home/beau/bar.txt

Ale tworzy symboliczne łącze do absolutnej nazwy ścieżki. Twoje pytanie tekstowe zawiera wzmiankę o względnej ścieżce ...

Zwykle względna nazwa ścieżki jest tym, czego chcesz i co ln -sci daje. Myślę, że chcesz:

cd /home/beau
ln -s foo/bar.txt bar.txt
MattBianco
źródło
1

Ponieważ najpopularniejsze powłoki rozszerzają ścieżki, aby utworzyć względne dowiązanie symboliczne, powinieneś zacytować „ścieżkę źródłową”.

Ponadto -sparametr oznacza --symbolic. lndomyślnie tworzy twarde linki.

$ ln -s '../../relative_path' path
$ ls -al path

lrwxrwxrwx 1 empjustine empjustine 19 Aug  6 01:38 path -> ../../relative/path
emp.justine
źródło
0

Jeśli jesteś pewien, że nie ma szansy na zmianę punktów montowania, możesz osiągnąć to, co próbujesz zrobić w powłoce bash:

ln -s `pwd`/bar.txt ~/bar.txt

Zakłada się, że podczas tworzenia dowiązania symbolicznego znajdujesz się w katalogu docelowym.

mreff555
źródło