Jaka jest różnica między „rm” a „unlink”?

55

Zakładając, że wiesz, że cel jest dowiązaniem symbolicznym, a nie plikiem, czy jest jakaś różnica między użyciem rma unlinkusunięciem łącza?

IQAndreas
źródło
3
Jest to dość dobrze omówione na ServerFault: serverfault.com/questions/38816/…
slm
@ slm ♦ Odpowiedzi odpowiadają na to pytanie, ale to pytanie jest inne, mówi: „Zakładając, że wiesz, że cel jest dowiązaniem symbolicznym, a nie plikiem”.
Stéphane Gourichon
Nie wygląda na to, że zaakceptowałeś tutaj odpowiedź @IQAndreas. Zrób to, jeśli ci pomogli.
Gray

Odpowiedzi:

56

Za każdym razem, gdy masz tego typu pytania, najlepiej zaplanować mały test, aby zobaczyć, co się właściwie dzieje. Do tego możesz użyć strace.

odczepić

$ touch file1
$ strace -s 2000 -o unlink.log unlink file1

rm

$ touch file1
$ strace -s 2000 -o rm.log rm file1

Gdy spojrzysz na 2 wynikowe pliki dziennika, możesz „zobaczyć”, co faktycznie robi każde połączenie.

Awaria

Po unlinkwywołaniu wywołania unlink()systemowego:

....
mmap(NULL, 106070960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6d025cc000
close(3)                                = 0
unlink("file1")                         = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
....

Ze rmjest to nieco inna droga:

....
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid()                               = 1000
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "file1", W_OK)      = 0
unlinkat(AT_FDCWD, "file1", 0)          = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
...

System wywołuje unlink()i unlinkat()jest zasadniczo taki sam, z wyjątkiem różnic opisanych na tej stronie podręcznika: http://linux.die.net/man/2/unlinkat .

fragment

Wywołanie systemowe unlinkat () działa dokładnie tak samo jak unlink (2) lub rmdir (2) (w zależności od tego, czy flagi zawierają flagę AT_REMOVEDIR), z wyjątkiem różnic opisanych na tej stronie podręcznika.

Jeśli nazwa ścieżki podana w nazwie ścieżki jest względna, to jest interpretowana w odniesieniu do katalogu, do którego odwołuje się deskryptor pliku dirfd (a nie względem bieżącego katalogu roboczego procesu wywołującego, jak to robi unlink (2) i rmdir (2) ) dla względnej nazwy ścieżki).

Jeśli nazwa ścieżki podana w pathname jest względna, a dirfd jest wartością specjalną AT_FDCWD, wówczas ścieżka jest interpretowana w odniesieniu do bieżącego katalogu roboczego procesu wywołującego (jak unlink (2) i rmdir (2)).

Jeśli nazwa ścieżki podana w pathname jest bezwzględna, to dirfd jest ignorowane.

slm
źródło
1
Ponieważ daje AT_FDCWD, nie ma różnicy między unlinki unlinkat.
Barmar
6
Z przyjemnością czytam tę odpowiedź, ponieważ po prostu „nauczyłem się łowić” w potężny, elastyczny sposób, kiedy często dostaję rybę lub czasami „uczę się łowić” w prosty sposób na SO :-)
mędrzec
21

POSIX określa, że unlinknarzędzie wywołuje funkcję biblioteki C unlinki nic więcej. Nie ma żadnej opcji. Jeśli przekażesz prawidłową nazwę ścieżki do czegoś, co nie jest katalogiem, i jeśli masz uprawnienia do zapisu w katalogu, w którym ten obiekt się znajduje, unlinkusuniesz ją.

rmto tradycyjne polecenie uniksowe, które ma trochę innych funkcji i nie jest całkiem nadzbiorem unlink(patrz poniżej).

Po pierwsze, rmprzeprowadza kontrole bezpieczeństwa. Jeśli spróbujesz rmuzyskać obiekt, do którego nie masz uprawnień do zapisu (które są nieistotne dla twojej możliwości usunięcia: bezpośrednie uprawnienia są!), rmJednak odmawia, chyba że -fokreślono inaczej . rmzwykle narzeka, jeśli plik nie istnieje, podobnie jak unlink; jednak ze -f, rmnie narzeka. Jest to często wykorzystywane w Makefiles ( clean: @rm -f $(OBJS) ...), więc make cleannie zawiedzie się, gdy nie będzie nic do usunięcia.

Po drugie, rmma -iopcję interaktywnego potwierdzania usunięcia.

Po trzecie, rmma -rdo rekursywnie usuwanie katalogu, który jest czymś, co unlinknie jest konieczne do zrobienia, ponieważ funkcja biblioteki C nie robi.

unlinkNarzędzie nie jest dokładnie okrojoną rm. Wykonuje podzbiór co rmrobi, ale ma semantykę, która jest połączeniem rm z -f i rm bez -f .

Załóżmy, że chcesz po prostu usunąć zwykły plik, niezależnie od jego uprawnień. Ponadto załóżmy, że chcesz, aby polecenie zakończyło się niepowodzeniem, jeśli plik nie istnieje lub z jakiegokolwiek innego powodu. Ani rm filenie rm -f filespełnia wymagań. rm fileodrzuci, jeśli pliku nie można zapisać. Ale rm -f filezignoruje reklamację, jeśli brakuje pliku. unlink filewykonuje pracę.

unlinkprawdopodobnie został wprowadzony, ponieważ rmjest zbyt sprytny: czasami po prostu chcesz czystej unlinksemantyki uniksowej : „Proszę, odejdź od tego wpisu katalogu, jeśli pozwalają na to uprawnienia katalogu” .

Kaz
źródło
2
Oto najjaśniejsza odpowiedź tutaj. To rzeczywiście daje przypadek użycia dla unlinkzamiast różnic prostu opisujących.
Wildcard
19

Za pomocą jednego pliku, rm i unlink wykonują to samo zadanie, usuń plik. Zgodnie z definicją POSIX rmi unlinkoba wywołują wywołanie systemowe unlink () .

W GNU rmwywołuje funkcję systemową unlinkat () , która jest równoważna funkcji unlink()lub rmdir (), z wyjątkiem przypadku, gdy ścieżka określa ścieżkę względną.

Uwaga

W niektórych systemach unlinkmożna również usunąć katalog. Przynajmniej w systemie GNU unlinknigdy nie można usunąć nazwy katalogu.

Cuonglm
źródło