Was ist der Unterschied zwischen 'rm' und 'unlink'?

55

Angenommen, Sie wissen, dass es sich bei dem Ziel um einen symbolischen Link und nicht um eine Datei handelt. Gibt es einen Unterschied zwischen der Verwendung rmund unlinkdem Entfernen des Links?

IQAndreas
quelle
3
Dies wird in ServerFault ziemlich gut behandelt: serverfault.com/questions/38816/…
slm
@ slm ♦ Die Antworten entsprechen dieser Frage, aber diese Frage lautet anders: "Vorausgesetzt, Sie wissen, dass das Ziel eine symbolische Verknüpfung und keine Datei ist".
Stéphane Gourichon
Sieht nicht so aus, als hättest du hier eine Antwort angenommen @IQAndreas. Bitte tun Sie dies, wenn sie Ihnen geholfen haben.
Grey

Antworten:

56

Wann immer Sie diese Art von Fragen haben, ist es am besten, sich einen kleinen Test auszudenken, um zu sehen, was tatsächlich passiert. Dafür können Sie verwenden strace.

Verknüpfung aufheben

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

rm

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

Wenn Sie sich die 2 resultierenden Protokolldateien ansehen, können Sie "sehen", was jeder Anruf tatsächlich tut.

Nervenzusammenbruch

Mit unlinkdem Aufruf des unlink()Systemaufrufs:

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

Mit rmes ist ein etwas anderer Weg:

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

Die Systemaufrufe unlink()und unlinkat()sind im Wesentlichen gleich mit Ausnahme der Unterschiede in dieser Manpage beschrieben: http://linux.die.net/man/2/unlinkat .

Auszug

Der Systemaufruf unlinkat () funktioniert genauso wie entweder unlink (2) oder rmdir (2) (abhängig davon, ob Flags das AT_REMOVEDIR-Flag enthalten oder nicht), mit Ausnahme der in dieser Handbuchseite beschriebenen Unterschiede.

Wenn der in pathname angegebene Pfadname relativ ist, wird er relativ zum Verzeichnis interpretiert, auf das der Dateideskriptor dirfd verweist (und nicht relativ zum aktuellen Arbeitsverzeichnis des aufrufenden Prozesses, wie dies bei unlink (2) und rmdir (2) der Fall ist ) für einen relativen Pfadnamen).

Wenn der in pathname angegebene Pfadname relativ und dirfd der Sonderwert AT_FDCWD ist, wird pathname relativ zum aktuellen Arbeitsverzeichnis des aufrufenden Prozesses interpretiert (wie unlink (2) und rmdir (2)).

Wenn der in pathname angegebene Pfadname absolut ist, wird dirfd ignoriert.

slm
quelle
1
Da es gibt AT_FDCWD, gibt es praktisch keinen Unterschied zwischen unlinkund unlinkat.
Barmar
6
Es freut mich, diese Antwort zu lesen, denn ich habe gerade gelernt, kraftvoll und flexibel zu fischen, wenn ich oft einen Fisch bekomme, oder manchmal lerne ich, auf einfache Weise auf SO zu fischen :-)
Salbei
20

POSIX gibt an, dass das unlinkDienstprogramm die C-Bibliotheksfunktion unlinkund nichts anderes aufruft . Es geht nicht anders. Wenn Sie einen gültigen Pfadnamen an etwas übergeben, das kein Verzeichnis ist, und wenn Sie über Schreibberechtigungen für das Verzeichnis verfügen, in dem sich das Objekt befindet, unlinkwird es entfernt.

rmist ein traditioneller Unix-Befehl, der über einige andere Funktionen verfügt und keine Obermenge von unlink(siehe unten) darstellt.

Führt zunächst rmSicherheitsprüfungen durch. Wenn Sie versuchen, auf rmein Objekt zuzugreifen, für das Sie keine Schreibrechte haben (die für Ihre Fähigkeit, es zu entfernen, unerheblich sind: die direkten Berechtigungen sind!), Wird dies rmdennoch abgelehnt, sofern nichts -fanderes angegeben ist. rmbeschwert sich normalerweise, wenn die Datei nicht existiert, wie es der Fall ist unlink; aber mit -f, rmbeschwert sich nicht. Dies wird oft in Makefiles ( clean: @rm -f $(OBJS) ...) ausgenutzt, so dass make cleanes nicht fehlschlägt, wenn nichts zu entfernen ist.

Zweitens rmhat die -iOption zur interaktiven Bestätigung des Löschvorgangs.

Drittens rmmuss -rein Verzeichnis rekursiv entfernt werden, was unlinknicht erforderlich ist, da die C-Bibliotheksfunktion dies nicht tut.

Das unlinkDienstprogramm ist nicht gerade ein abgespecktes rm. Es führt eine Teilmenge dessen durch, was es rmtut, aber es hat eine Semantik, die eine Kombination von rm mit -f und ohne rm ist -f.

Angenommen, Sie möchten nur eine reguläre Datei entfernen, unabhängig von ihren eigenen Berechtigungen. Angenommen, der Befehl schlägt fehl, wenn die Datei nicht vorhanden ist, oder aus einem anderen Grund. Weder erfüllt rm filenoch rm -f filedie Anforderungen. rm filelehnt ab, wenn die Datei nicht beschreibbar ist. Werde rm -f filemich aber nicht beschweren, wenn die Datei fehlt. unlink filemacht den Job.

unlinkwurde wahrscheinlich eingeführt , weil rmzu klug ist: manchmal nur die reine Sie Unix wollen unlink: Semantik „ wenn Verzeichnisberechtigungen erlauben Sie diesen Verzeichniseintrag weggehen“ .

Kaz
quelle
2
Dies ist die klarste Antwort hier. Tatsächlich wird der Anwendungsfall angegeben, um unlinkUnterschiede nicht nur zu beschreiben.
Wildcard
19

Mit einer einzelnen Datei erledigen rm und unlink dieselbe Aufgabe, entfernen Sie die Datei. Wie in POSIX definiert, rmund unlinkbeide rufen den Systemaufruf unlink () auf.

In GNU rmruft es den Systemaufruf unlinkat () auf, der der Funktion unlink()or rmdir () entspricht, außer wenn path einen relativen Pfad angibt.

Hinweis

Auf einigen Systemen unlinkkann auch das Verzeichnis entfernt werden. Zumindest im GNU-System unlinkkann der Name eines Verzeichnisses nie gelöscht werden.

cuonglm
quelle