En supposant que vous sachiez que la cible est un lien symbolique et non un fichier, existe-t-il une différence entre utiliser rm
et unlink
supprimer le lien?
En supposant que vous sachiez que la cible est un lien symbolique et non un fichier, existe-t-il une différence entre utiliser rm
et unlink
supprimer le lien?
Réponses:
Chaque fois que vous avez ce type de questions, il est préférable de concevoir un petit test pour voir ce qui se passe réellement. Pour cela, vous pouvez utiliser strace
.
$ touch file1
$ strace -s 2000 -o unlink.log unlink file1
$ touch file1
$ strace -s 2000 -o rm.log rm file1
Lorsque vous examinez les 2 fichiers journaux résultants, vous pouvez "voir" ce que fait réellement chaque appel.
Avec unlink
l'appel de l' unlink()
appel système:
....
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) = ?
....
Avec rm
c'est un chemin légèrement différent:
....
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 +++
...
Les appels système unlink()
et unlinkat()
sont essentiellement les mêmes, à l'exception des différences décrites dans cette page de manuel: http://linux.die.net/man/2/unlinkat .
L'appel système unlinkat () fonctionne exactement de la même manière que unlink (2) ou rmdir (2) (selon que les options incluent ou non l'indicateur AT_REMOVEDIR), à l'exception des différences décrites dans cette page de manuel.
Si le nom de chemin indiqué dans chemin est relatif, il est interprété par rapport au répertoire référencé par le descripteur de fichier dirfd (plutôt que par rapport au répertoire de travail actuel du processus appelant, comme le font par unlink (2) et rmdir (2). ) pour un chemin relatif).
Si le nom de chemin indiqué dans chemin est nom relatif et que dirfd est la valeur spéciale AT_FDCWD, le chemin est interprété par rapport au répertoire de travail actuel du processus appelant (comme unlink (2) et rmdir (2)).
Si le chemin indiqué dans chemin est absolu, alors dirfd est ignoré.
AT_FDCWD
, il n'y a effectivement aucune différence entre unlink
et unlinkat
.
POSIX spécifie que l' unlink
utilitaire appelle la unlink
fonction de bibliothèque C et rien d'autre. Cela ne prend aucune option. Si vous transmettez un nom de chemin valide à quelque chose qui n'est pas un répertoire et si vous disposez d'autorisations en écriture sur le répertoire où cet objet réside, vous unlink
le supprimerez.
rm
est une commande Unix traditionnelle qui a un peu d'autres fonctionnalités et qui n'est pas vraiment un sur-ensemble unlink
(voir ci-dessous).
Tout d'abord, rm
effectue des contrôles de sécurité. Si vous essayez rm
un objet pour lequel vous ne possédez pas d’autorisation en écriture (qui n’a aucune incidence sur votre capacité à le supprimer: les autorisations directes le sont!) rm
Refuse néanmoins sauf si -f
est spécifié. rm
se plaint normalement si le fichier n'existe pas, comme c'est le cas unlink
; cependant avec -f
, rm
ne se plaint pas. Ceci est souvent exploité dans Makefiles ( clean: @rm -f $(OBJS) ...
), donc make clean
n'échoue pas lorsqu'il n'y a rien à supprimer.
Deuxièmement, rm
a la -i
possibilité de confirmer de manière interactive la suppression.
Troisièmement, il rm
faut -r
supprimer récursivement un répertoire, ce qui unlink
n’est pas obligatoire, car la fonction de bibliothèque C ne le fait pas.
L' unlink
utilitaire n'est pas vraiment un dépouillé rm
. Il exécute un sous-ensemble de ce qui rm
fonctionne, mais il a une sémantique qui est une combinaison de rm
with -f
et rm without -f
.
Supposons que vous souhaitiez simplement supprimer un fichier normal, quelles que soient ses propres autorisations. De plus, supposez que vous souhaitiez que la commande échoue si le fichier n'existe pas ou pour toute autre raison. Ni rm file
ni rm -f file
répond aux exigences. rm file
refusera si le fichier n'est pas accessible en écriture. Mais rm -f file
néglige de se plaindre si le fichier est manquant. unlink file
Fait le travail.
unlink
a probablement été introduit parce qu’il rm
est trop intelligent: parfois, vous voulez juste la unlink
sémantique Unix pure : "veuillez faire en sorte que cette entrée de répertoire disparaisse si les autorisations de répertoire le permettent" .
unlink
plutôt que de simplement décrire les différences.
Avec un seul fichier, rm et unlink effectuent la même tâche, supprimez le fichier. Comme défini POSIX, rm
et à la unlink
fois appel à unlink () appel système.
Dans GNU rm
, il appelle l’ appel système unlinkat () , ce qui équivaut à la fonction unlink()
ou à la fonction rmdir () , sauf dans le cas où chemin spécifie un chemin relatif.
Remarque
Sur certains systèmes, unlink
peut également supprimer un répertoire. Au moins dans le système GNU, unlink
ne peut jamais supprimer le nom d’un répertoire.