Czy jakikolwiek system operacyjny zapewnia mechanizm (wywołanie systemowe - nie program wiersza poleceń) do zmiany ścieżki, do której odwołuje się dowiązanie symboliczne (dowiązanie symboliczne) - inne niż przez odłączenie starego i utworzenie nowego?
Standard POSIX tego nie robi. Solaris 10 nie. MacOS X 10.5 (Leopard) nie. (Jestem całkiem pewien, że ani AIX, ani HP-UX też nie. Sądząc po liście wywołań systemowych Linuksa, Linux również nie ma takiego wywołania systemowego).
Czy jest coś, co robi?
(Oczekuję, że odpowiedź brzmi „Nie”).
Ponieważ udowodnienie czegoś negatywnego jest trudne, przeorganizujmy pytanie.
Jeśli wiesz, że jakiś (podobny do systemu Unix) system operacyjny, którego nie ma jeszcze na liście, nie ma żadnego wywołania systemowego do przepisywania wartości dowiązania symbolicznego (ciąg zwracany przez readlink()
) bez usuwania starego dowiązania symbolicznego i tworzenia nowego, dodaj go - lub je - w odpowiedzi.
ln
polecenia (lub równoważnika API) nadpisującego stare łącze? Jaki masz problem?Odpowiedzi:
AFAIK, nie, nie możesz. Musisz go usunąć i odtworzyć.Właściwie możesz nadpisać łącze symboliczne i zaktualizować w ten sposób ścieżkę, do której się ono odwołuje:EDYCJA : Jak OP wskazał w komentarzu, użycie
--force
opcji spowodujeln
wykonanie wywołania systemowegounlink()
wcześniejsymlink()
. Poniżej wyjście zstrace
mojego Linux-a, które to potwierdza:Więc myślę, że ostateczna odpowiedź brzmi „nie”.EDYCJA : Poniższy tekst jest skopiowany z odpowiedzi Arto Bendikena na unix.stackexchange.com, około 2016 r.
To może być rzeczywiście wykonywane atomowo z
rename(2)
, najpierw tworzenia nowego dowiązania pod tymczasową nazwą, a następnie czysto nadpisanie starego dowiązania w jednym zamachem. Jak stwierdza strona podręcznika :W powłoce zrobiłbyś to
mv -T
w następujący sposób:Możesz
strace
to ostatnie polecenie, aby upewnić się, że rzeczywiście używarename(2)
pod maską:Zauważ, że w powyższym, oba
mv -T
istrace
są specyficzne dla Linuksa.We FreeBSD używaj
mv -h
naprzemiennie.Uwaga redaktora: Tak robi Capistrano od lat, od czasu ~ 2.15. Zobacz to żądanie ściągnięcia .
źródło
Tak, możesz!
źródło
-f
środki opcja „usunąć istniejący cel” przed utworzeniem nowego. Tak więc to polecenie osiąga wynik, ale przez wykonanie,unlink(2)
po którym następujesymlink(2)
. Nie o to chodziło w pierwotnym pytaniu. Zauważ również, że zaakceptowana odpowiedź i kolejna najczęściej głosowana odpowiedź służąln -sf
do wykonania zadania, ale jakstrace
widać na wyjściu, robi tounlink()
isymlink()
ponieważ nie ma wywołania systemowego modyfikującego dowiązanie symboliczne.Nie jest konieczne jawne odłączanie starego łącza symbolicznego. Możesz to zrobić:
(lub użyj równoważnego łącza symbolicznego i zmień nazwę wywołań). Jest to lepsze niż jawne odłączanie, ponieważ zmiana nazwy jest atomowa, więc możesz mieć pewność, że łącze zawsze będzie wskazywać na stary lub nowy cel. Jednak nie spowoduje to ponownego wykorzystania oryginalnego i-węzła.
W niektórych systemach plików cel dowiązania symbolicznego jest przechowywany w samym i-węźle (w miejscu listy bloków), jeśli jest wystarczająco krótki; jest to określone w momencie tworzenia.
Jeśli chodzi o stwierdzenie, że rzeczywisty właściciel i grupa są nieistotni, link symboliczny (7) w Linuksie mówi, że istnieje przypadek, w którym jest to znaczące:
źródło
set -x -e; mkdir junk; ( cd junk; mkdir olddir newdir; ln -s olddir mylink; ls -ilR; ln -s newdir temp; ls -ilR; mv temp mylink; ls -ilR; ); rm -fr junk
. Jeśli zamiast katalogów utworzysz pliki oldfile i newfile i uruchomisz odpowiedni skrypt (głównie zmieniając olddir na oldfile, newdir na newfile), uzyskasz oczekiwany efekt. Tylko jedna dodatkowa złożoność! Dziękuję za odpowiedź.Tylko ostrzeżenie przed poprawnymi odpowiedziami powyżej:
Użycie metody -f / --force stwarza ryzyko utraty pliku w przypadku pomieszania źródła i celu:
Oczywiście jest to zamierzone, ale zwykle zdarzają się błędy. Tak więc usunięcie i odbudowanie linku symbolicznego wymaga trochę więcej pracy, ale także trochę oszczędności:
który przynajmniej zachowuje mój plik.
źródło
-f
lub--force
jest zawsze nieco niebezpieczne; zakłada, że użytkownik wie, o co mu chodzi. Jest podwójnie zabójczy, jeśli używasz go nałogowo (zarm -fr …
każdym razem jest to niebezpieczne).Czy odłączenie go i utworzenie nowego i tak nie zrobiłoby tego samego?
źródło
ln --force
polecenie całkowicie nadpisze istniejące łącze.ln (1)
, podczas gdy Matt B. omawia fakt, żesymlink (2)
ma nie obsługuje nadpisywania. Oboje macie rację i sugerowałbym, że przyjrzenie się implementacjiln (1)
dałoby najbardziej idomatyczny sposób wykonania procedury rozłączania i ponownego łączenia.Na wszelki wypadek to pomoże: istnieje sposób na edycję linku symbolicznego za pomocą Midnight Commander (mc). Polecenie menu to (po francusku na moim interfejsie mc):
które można przetłumaczyć na:
Skrót to Cx Cs
Może wewnętrznie używa
ln --force
polecenia, nie wiem.Teraz próbuję znaleźć sposób na edycję wielu linków symbolicznych naraz (w ten sposób tu dotarłem).
źródło
unlink()
następujesymlink()
po prostu a , po prostu dlatego, że zapewniają to systemy podobne do Uniksa.Technicznie rzecz biorąc, nie ma wbudowanego polecenia do edycji istniejącego łącza symbolicznego. Można to łatwo osiągnąć za pomocą kilku krótkich poleceń.
Oto mała funkcja bash / zsh, którą napisałem, aby zaktualizować istniejący link symboliczny:
źródło
unlink()
isymlink()
z nową wartością, która jest, co dzieje się za kulisami z kodem. Osobiście chciałbym, aby funkcja nalegała na dokładnie dwa (lub być może wielokrotność dwóch) argumentów i zwolniłaby, gdyby wywołanie nie było poprawne. To jednak szczególna perspektywa.