2009-09-06 26 views
18

Chciałbym zmienić cel dowiązania symbolicznego w skrypcie basha. Problemem jest to, że dowiązanie jest bardzo ważne (to /bin/sh, mianowicie) i chciałbym zrobić to w sposób, który:Zamień ważne dowiązanie symboliczne "bezpiecznie"

  1. Nowy cel będą dostępne natychmiast po usunięciu starych, czyli nie będzie możliwości, że coś będzie Zauważ, że zniknie,
  2. Nie będzie żadnej możliwości, że zmiana zakończy się niepowodzeniem w środku, tj. usunięcie użytkownika z usuniętym dowiązaniem symbolicznym i brak nowego.

Myślałem o dwóch metodach. Albo za pomocą zwykłego ln:

ln -fs /bin/bash /bin/sh 

lub używając mv:

ln -s /bin/bash /bin/sh.new 
mv /bin/sh.new /bin/sh 

Które jeden lepiej spełnić moje potrzeby? Czy jest jakaś możliwość, że jeden z nich spróbuje zastąpić cel dowiązania symbolicznego zamiast samego dowiązania symbolicznego?

Odpowiedz

22

Zmiana nazwy (mv) jest operacją atomową; tworzenie nowego dowiązania symbolicznego nie jest (usuń stare dowiązanie symboliczne, utwórz nowe). Więc należy użyć mv:

$ ln -s new current_tmp && mv -Tf current_tmp current 

Oto blog post omawianie tego. Ponadto, jeśli martwisz się tym, co się stanie, może spróbuj najpierw na niekrytycznym dowiązaniu symbolicznym?

+1

Nie możesz być pewien, że nie wystąpią potencjalne problemy, jeśli po prostu spróbujesz tego :). Bardzo trudno jest zrobić test dla "coś Zawiadomienie znikające ". – Eugene

+1

O poście na blogu - '-T' nie wydaje się być opcją przenośną. –

-1

Wygląda na to (ze strony podręcznika) ln -f rozłącza dowiązanie symboliczne przed utworzeniem nowego, co oznacza, że ​​lepszym rozwiązaniem jest tutaj mv.

Zdecydowanie jednak polecam przeciwko łączenie /bin/sh z bash. Wiele skryptów używa:

#!/bin/sh 

i są napisane przy założeniu, że powłoka jest klasyczną skorupą Bourne'a. Jeśli zamiast tego miałby działać jako bash, można łatwo uzyskać niejasne niezgodności między tym, co skrypt przyjmuje: sh, a tym, co robi skrypt. Będzie to prawie niemożliwe do wyśledzenia.

+5

Z wyjątkiem oczywiście faktu, że na wielu systemach/bin/sh * jest * dowiązaniem symbolicznym do/bin/bash; a po wywołaniu za jego pośrednictwem bash wejdzie w tryb zgodności sh. –

+0

bash nie może być zgodny z sh. Spróbuj tego w prawdziwym sh i bash: i = 0; ls | while read a; do i = expr $ i + 1; Gotowe ; echo $ i Jeśli robisz nie masz prawdziwego sh, spróbuj z ksh Zwróć uwagę, że powyższy wynik różni się nawet między wersjami sh. Na solaris bardzo stare sh wydrukuje 0, podczas gdy wersja xpg4 daje niezerową (jak ksh) – Gunstick

+1

@Gun: tak, dlatego, że "sh" nie może być "sh" -kompatybilne (to właśnie mówisz). .. tak, jasne, wtedy nic, łącznie z bash, nie może być zgodne z wszelkim niezdefiniowanym zachowaniem starych "sh".To, co bash * może * być, jest jednak kompatybilne z jakimś powszechnie przyjętym/akceptowanym/zdefiniowanym sh-standardem. Na myśl przychodzą POSIX lub SUSv2. –

Powiązane problemy