Qual è la differenza tra 'rm' e 'unlink'?


55

Supponendo che tu sappia che la destinazione è un collegamento simbolico e non un file, c'è qualche differenza tra l'utilizzo rme la unlinkrimozione del collegamento?


3
Questo è abbastanza ben coperto su ServerFault: serverfault.com/questions/38816/…
slm

@ slm ♦ Le risposte corrispondono a quella domanda, ma questa domanda è diversa, dice: "Supponendo che tu sappia che il bersaglio è un collegamento simbolico e non un file".
Stéphane Gourichon,

Non sembra che tu abbia accettato una risposta qui @IQAndreas. Per favore, fallo se ti hanno aiutato.
Grey,

Risposte:


56

Ogni volta che hai questo tipo di domande, è meglio concepire un piccolo test per vedere cosa sta realmente accadendo. Per questo puoi usare strace.

unlink

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

rm

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

Quando dai un'occhiata ai 2 file di registro risultanti puoi "vedere" cosa sta effettivamente facendo ogni chiamata.

Abbattersi

Con il unlinksuo invocare la unlink()chiamata di sistema:

....
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)                           = ?
....

Con rmè un percorso leggermente diverso:

....
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 +++
...

Il sistema chiama unlink()e unlinkat()sono essenzialmente gli stessi, tranne per le differenze descritte in questa pagina man: http://linux.die.net/man/2/unlinkat .

estratto

La chiamata di sistema unlinkat () funziona esattamente allo stesso modo di unlink (2) o rmdir (2) (a seconda che i flag includano o meno il flag AT_REMOVEDIR) ad eccezione delle differenze descritte in questa pagina di manuale.

Se il nome percorso indicato nel nome percorso è relativo, viene interpretato in relazione alla directory a cui fa riferimento il descrittore di file dirfd (anziché relativo alla directory di lavoro corrente del processo chiamante, come viene fatto da unlink (2) e rmdir (2 ) per un percorso relativo).

Se il nome percorso indicato in nome percorso è relativo e dirfd è il valore speciale AT_FDCWD, il percorso viene interpretato in relazione alla directory di lavoro corrente del processo chiamante (come unlink (2) e rmdir (2)).

Se il nome percorso indicato nel nome percorso è assoluto, dirfd viene ignorato.


1
Dal momento che sta dando AT_FDCWD, non c'è effettivamente alcuna differenza tra unlinke unlinkat.
Barmar,

6
Mi rende felice leggere questa risposta perché ho appena "imparato a pescare" in modo potente e flessibile quando spesso prendo un pesce o a volte "imparo a pescare" in modo basilare su SO :-)
saggio

22

POSIX specifica che l' unlinkutilità chiama la unlinkfunzione di libreria C e nient'altro. Non ci vuole alcuna opzione. Se si passa un nome percorso valido a qualcosa che non è una directory e se si dispone delle autorizzazioni di scrittura per la directory in cui si trova l'oggetto, unlinklo rimuoverà.

rmè un comando Unix tradizionale che ha un po 'di altre funzionalità e non è abbastanza un superset di unlink(vedi sotto).

Innanzitutto, rmesegue i controlli di sicurezza. Se provi a rmun oggetto per il quale non hai i permessi di scrittura (che sono irrilevanti per la tua capacità di rimuoverlo: i permessi diretti sono!) Si rmrifiuta comunque a meno che non -fsia specificato. rmnormalmente si lamenta se il file non esiste, come fa unlink; tuttavia con -f, rmnon si lamenta. Questo è spesso sfruttato in Makefiles ( clean: @rm -f $(OBJS) ...) quindi make cleannon fallisce quando non c'è nulla da rimuovere.

In secondo luogo, rmha l' -iopzione per confermare interattivamente l'eliminazione.

In terzo luogo, rmha la -rrimozione ricorsiva di una directory, che è qualcosa che unlinknon è necessario fare, dal momento che la funzione di libreria C non lo fa.

L' unlinkutilità non è esattamente una riduzione rm. Esegue un sottoinsieme di ciò che rmfa, ma ha una semantica che è una combinazione di rm con -f e rm senza -f .

Supponiamo di voler rimuovere un file normale indipendentemente dalle autorizzazioni proprie. Supponiamo inoltre che tu voglia che il comando fallisca se il file non esiste o per qualsiasi altro motivo. rm filerm -f filesoddisfa i requisiti. rm filerifiuterà se il file non è scrivibile. Ma rm -f filetrascurerà di lamentarsi se il file è mancante. unlink filefa il lavoro.

unlinkè stato probabilmente introdotto perché rmtroppo intelligente: a volte vuoi solo la unlinksemantica Unix pura : "per favore, fai in modo che questa voce della directory scompaia se i permessi della directory lo consentono" .


2
Questa è la risposta più chiara qui. Dà in realtà il caso d'uso per unlinkpiuttosto che le differenze solo che descrivono.
Carattere jolly

19

Con un singolo file, rm e unlink svolgono la stessa attività, rimuovono il file. Come definito da POSIX, rmed unlinkentrambi chiamano unlink () chiamata di sistema.

In GNU rm, chiama a unlinkat () chiamata di sistema, che è equivalente alla funzione unlink()o rmdir () , tranne nel caso in cui path specifichi un percorso relativo.

Nota

Su alcuni sistemi, unlinkè anche possibile rimuovere la directory. Almeno nel sistema GNU, unlinknon è mai possibile eliminare il nome di una directory.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.