Qual é a diferença entre 'rm' e 'unlink'?

41

Supondo que você saiba que o alvo é um link simbólico e não um arquivo, existe alguma diferença entre usar rm e unlink para remover o link?

    
por IQAndreas 24.08.2014 / 21:03

3 respostas

42

Sempre que você tiver esses tipos de perguntas, é melhor conceber um pequeno teste para ver o que realmente está acontecendo. Para isso, você pode usar strace .

desvincular

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

rm

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

Quando você der uma olhada nos 2 arquivos de log resultantes, poderá "ver" o que cada chamada está realmente fazendo.

Divisão

Com unlink , ele está chamando a chamada do sistema unlink() :

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

Com rm é um caminho ligeiramente diferente:

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

As chamadas de sistema unlink() e unlinkat() são essencialmente as mesmas, exceto pelas diferenças descritas nesta página man: link .

trecho

The unlinkat() system call operates in exactly the same way as either unlink(2) or rmdir(2) (depending on whether or not flags includes the AT_REMOVEDIR flag) except for the differences described in this manual page.

If the pathname given in pathname is relative, then it is interpreted relative to the directory referred to by the file descriptor dirfd (rather than relative to the current working directory of the calling process, as is done by unlink(2) and rmdir(2) for a relative pathname).

If the pathname given in pathname is relative and dirfd is the special value AT_FDCWD, then pathname is interpreted relative to the current working directory of the calling process (like unlink(2) and rmdir(2)).

If the pathname given in pathname is absolute, then dirfd is ignored.

    
por 24.08.2014 / 21:35
18

Com um único arquivo, rm e desvincular faça a mesma tarefa, remova o arquivo. Como POSIX definido, rm e unlink chamam a unlink () chamada de sistema.

No GNU rm , ele chama a chamada de sistema unlinkat () , que é equivalente à função unlink() ou rmdir () , exceto no caso em que path especifica um parente caminho.

Nota

Em alguns sistemas, unlink também pode remover o diretório. Pelo menos no sistema GNU, unlink nunca pode apagar o nome de um diretório.

    
por 24.08.2014 / 21:26
10

POSIX especifica que o utilitário unlink chama a função unlink da biblioteca C e nada mais. Não tem opção. Se você passar um nome de caminho válido para algo que não é um diretório, e se você tiver permissões de gravação para o diretório onde o objeto vive, então unlink irá removê-lo.

rm é um comando tradicional do Unix que tem um pouco de outra funcionalidade e não é exatamente um superconjunto de unlink (veja abaixo).

Primeiramente, rm realiza verificações de segurança. Se você tentar rm um objeto para o qual você não tem permissões de gravação (que são irrelevantes para sua capacidade de removê-lo: as permissões diretamente são!) rm , no entanto, recusa a menos que -f seja especificado. rm normalmente reclama se o arquivo não existe, assim como unlink ; no entanto, com -f , rm não reclama. Isso geralmente é explorado em Makefiles ( clean: @rm -f $(OBJS) ... ), então make clean não falha quando não há nada para remover.

Em segundo lugar, rm tem a opção -i para confirmar a exclusão interativamente.

Em terceiro lugar, rm tem -r para remover recursivamente um diretório, que é algo que unlink não é necessário, já que a função da biblioteca C não faz isso.

O utilitário unlink não é exatamente um rm . Ele executa um subconjunto do que rm faz, mas tem semântica que é uma combinação de rm com -f e rm sem -f .

Suponha que você queira apenas remover um arquivo regular, independentemente de quais são suas próprias permissões. Além disso, suponha que você queira que o comando falhe se o arquivo não existir ou por qualquer outro motivo. Nem rm file nem rm -f file atende aos requisitos. rm file recusará se o arquivo não for gravável. Mas rm -f file irá deixar de reclamar se o arquivo estiver faltando. unlink file faz o trabalho.

unlink foi provavelmente introduzido porque rm é muito inteligente: às vezes você quer apenas a semântica unlink pura do Unix: "faça essa entrada do diretório desaparecer se as permissões de diretório permitirem" .

    
por 29.11.2016 / 02:40

Tags