Dlaczego mój symboliczny link nie działa?

24

Próbuję lepiej zrozumieć dowiązania symboliczne ... i nie mam dużo szczęścia. Oto moje rzeczywiste wyjście powłoki ze zmienioną nazwą użytkownika / hosta:

username@host:~$ mkdir actual
username@host:~$ mkdir proper
username@host:~$ touch actual/file-1.txt
username@host:~$ echo "file 1" > actual/file-1.txt
username@host:~$ touch actual/file-2.txt
username@host:~$ echo "file 2" > actual/file-2.txt
username@host:~$ ln -s actual/file-1.txt actual/file-2.txt proper
username@host:~$ # Now, try to use the files through their links
username@host:~$ cat proper/file-1.txt
cat: proper/file-1.txt: No such file or directory
username@host:~$ cat proper/file-2.txt
cat: proper/file-2.txt: No such file or directory
username@host:~$ # Check that actual files do in fact exist
username@host:~$ cat actual/file-1.txt
file 1
username@host:~$ cat actual/file-2.txt
file 2
username@host:~$ # Remove the links and go home :(
username@host:~$ rm proper/file-1.txt
username@host:~$ rm proper/file-2.txt

Myślałem, że dowiązanie symboliczne powinno działać w sposób przezroczysty, w tym sensie, że możesz operować na pliku, który wskazuje, tak jakbyś miał bezpośredni dostęp do pliku (z wyjątkiem oczywiście sytuacji, w rmktórych link jest po prostu usuwany ).

orokusaki
źródło
Jak sformatowany jest Twój dysk? Z jakiego systemu plików korzystasz? (FAT nie obsługuje dowiązań symbolicznych, ale jeśli spróbujesz zrobić na systemie plików FAT, powinien dać błąd.)
Nicole Hamilton
@NicoleHamilton - To ext4 (zgodnie z df -T) - czy powyższy wynik też jest dla Ciebie dziwny?
orokusaki
@orokusaki Nie dziwne. Zobacz moją odpowiedź poniżej. Tylko jedna głowa do góry, nie trzeba dotykać plików, aby do nich dotrzeć. Nie muszą nawet istnieć. Aby zaoszczędzić trochę pisania!
nerdwaller

Odpowiedzi:

50

Dowiązania symboliczne zwykle lubią pełne ścieżki lub są względne względem łącza, w przeciwnym razie często mogą szukać file-1.txtlokalnie (co dziwne).

Nawiguj properi wykonuj, ls -la zobaczysz, że dowiązanie symboliczne szuka actual/file-1.txt, kiedy powinno ../actual/file-1.txt.

Masz więc dwie opcje:

  1. Podaj pełną ścieżkę

    ln -s ~/actual/file-1.txt ~/actual/file-2.txt ~/proper
  2. Przejdź do folderu, w którym ma znajdować się link, i stamtąd link

    cd proper
    ln -s ../actual/file-1.txt ../actual/file-2.txt ./

Edycja : wskazówka, aby zapisać pisanie.

Możesz po prostu zrobić ln -s ~/actual/file-{1,2}.txt ~/proper

Elementy w nawiasach klamrowych są zastępowane i umieszczane jeden za drugim, tworząc polecenie

ln -s ~/actual/file-1.txt ~/actual/file-2.txt ~/proper

który łączy oba pliki z katalogiem docelowym. Oszczędza trochę pisania na klawiaturze w miarę wchodzenia w powłokę.

nerdwaller
źródło
2
Dzięki - właśnie miałem wyciągnąć włosy, zanim przeczytam twoją odpowiedź.
orokusaki
1
Czasami jest to mylące! Linux wydaje się być bardzo dosłowny, więc jeśli powiesz coś zrób - zrobi to. Bądź ostrożny z łączeniem folderów w ten sposób, wcześniej nadpisałem jeden lub dwa (po prostu określ nazwę bez końcowego ukośnika). Nie rm -rf *wchodź też do folderu z dowiązaniami symbolicznymi - możesz wyczyścić folder, do którego prowadzi. Po prostu wykonaj rm symlinkname. Kilka rzeczy, w których popełniłem błędy: D
nerdwaller
3

Problemem jest użycie ścieżek względnych. Jeśli określisz tworzenie linku z pełną jawną ścieżką, to zadziała.

$ ln -s ~ / rzeczywisty / plik1.txt ~ / aktualny / plik2.txt ~ / właściwy /

$ cat właściwy / plik1.txt

plik 1

$

Twój przykład tworzy linki w propertym wyglądzie podkatalogu o nazwie rzeczywisty w bieżącym katalogu, a nie zamierzonego elementu nadrzędnego dla obu.

Don Simon
źródło
1

Dowiązania symboliczne mogą być trudne. Zasadniczo dowiązanie symboliczne to plik zawierający nazwę pliku / ścieżkę do innego pliku (oznaczony do specjalnego traktowania). Jeśli nazwa ścieżki w pliku łącza zaczyna się od „ /”, to jest traktowana jako bezwzględna nazwa ścieżki, a sprawy są dość proste. Jeśli nie zaczyna się od ukośnika, jest traktowany jako względna nazwa ścieżki - względem katalogu, w którym znajduje się łącze. (Dzieje się tak niezależnie od tego, czy nazwa zawiera ukośniki.) Tak więc utworzyłeś proper/file–1.txtlink do „ actual/file–1.txt”, a kiedy próbowałeś uzyskać do niego dostęp, system próbował uzyskać dostęp proper/actual/file–1.txt. Powinieneś był powiedzieć

ln s  ../actual/file1.txt  ../actual/file2.txt  proper

Nawiasem mówiąc, nie potrzebowałeś touchpoleceń.  echo "file 1" > actual/file–1.txtwystarczy stworzyć actual/file–1.txt.

Scott
źródło
0

Powiązany problem, który może być oczywisty dla wielu, ale zaskoczył mnie na kilka minut: jeśli tworzysz dowiązanie symboliczne w katalogu, który sam jest dowiązaniem symbolicznym, lub istnieje dowiązanie symboliczne w ścieżce bieżącego katalogu roboczego, możesz napotykają problemy z niedziałającymi dowiązaniami symbolicznymi.

Używaj cd ..i ls -lkilkakrotnie, aby sprawdzić, czy Twoje katalogi nadrzędne same są połączone symbolicznie.

Jeśli musisz utworzyć dowiązanie symboliczne, cddo oryginalnego katalogu docelowego i tam utworzyć nowe dowiązania symboliczne, aby ścieżki względne były dokładne.

Innymi słowy: ścieżka względna prowadzi od początku do celu. Jeśli źródło jest następnie dowiązane symbolicznie, to jest OK. Ale możesz napotkać problemy z konfiguracją nowego Origin link_name w katalogu, który sam jest w jakiś sposób symlinkowany.

Chrisky
źródło
1
Zamiast „ cd ..i ls -lwielokrotnie” możesz użyć namei -mox $PWD. Innym przydatnym sposobem sprawdzenia, czy na ścieżce są dowiązania symboliczne, jest użycie ścieżki pwd -P, która daje ścieżkę do bieżącego katalogu, który nie zawiera żadnych dowiązań symbolicznych (więc jeśli pwdi pwd -Pdaje inne dane wyjściowe, wiesz, że gdzieś po drodze jest dowiązanie symboliczne ).
Ansa211,
0

Kiedy próbujesz utworzyć link do pliku, który nie istnieje (lub podałeś nieprawidłową ścieżkę), ln -s nie zgłasza błędu. Tworzy link, ale gdy spróbujesz użyć „cat” na tym linku, nie zostanie znaleziony żaden plik. Nawet jeśli możesz to zobaczyć za pomocą ls. W takich przypadkach zawsze dwukrotnie sprawdź ścieżkę do pliku.

ubuntu@ip-172-31-80-155:~/lab5$ ln -s etc/ufw/ufw.conf link1
ubuntu@ip-172-31-80-155:~/lab5$ ls -al
total 5360
drwxrwxr-x 2 ubuntu ubuntu    4096 Mar  9 18:56 .
drwxr-xr-x 7 ubuntu ubuntu    4096 Mar  9 18:42 ..
-rwxr--r-- 1 ubuntu ubuntu 5478400 Mar  9 18:32 backup.tar
lrwxrwxrwx 1 ubuntu ubuntu      16 Mar  9 18:56 link1 -> etc/ufw/ufw.conf
ubuntu@ip-172-31-80-155:~/lab5$ cat link1
cat: link1: No such file or directory

Ponieważ plik etc / ufw / ufw.conf nie istnieje. Prawidłowa ścieżka to /etc/ufw/ufw.conf

ubuntu@ip-172-31-80-155:~/lab5$ ln -s /etc/ufw/ufw.conf link2
ubuntu@ip-172-31-80-155:~/lab5$ ls -l
total 5352
-rwxr--r-- 1 ubuntu ubuntu 5478400 Mar  9 18:32 backup.tar
lrwxrwxrwx 1 ubuntu ubuntu      16 Mar  9 18:56 link1 -> etc/ufw/ufw.conf
lrwxrwxrwx 1 ubuntu ubuntu      17 Mar  9 19:00 link2 -> /etc/ufw/ufw.conf
ubuntu@ip-172-31-80-155:~/lab5$ cat link2
# /etc/ufw/ufw.conf
#

# Set to yes to start on boot. If setting this remotely, be sure to add a rule
# to allow your remote connection before starting ufw. Eg: 'ufw allow 22/tcp'
ENABLED=no

# Please use the 'ufw' command to set the loglevel. Eg: 'ufw logging medium'.
# See 'man ufw' for details.
LOGLEVEL=low
sindhura
źródło
Jest już lepsza odpowiedź, a pierwsza część, że ln -s„czasami” nie sprawdza istnienia celu jest po prostu błędna.
RalfFriedl