Supondo que você saiba que o destino é um link simbólico e não um arquivo, existe alguma diferença entre usar rm
e unlink
remover o link?
Supondo que você saiba que o destino é um link simbólico e não um arquivo, existe alguma diferença entre usar rm
e unlink
remover o link?
Respostas:
Sempre que você tiver esse tipo de pergunta, é melhor conceber um pequeno teste para ver o que realmente está acontecendo. Para isso você pode usar strace
.
$ touch file1
$ strace -s 2000 -o unlink.log unlink file1
$ touch file1
$ strace -s 2000 -o rm.log rm file1
Quando você olha os 2 arquivos de log resultantes, pode "ver" o que cada chamada está realmente fazendo.
Com unlink
isso, é chamada a chamada do unlink()
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) = ?
....
Com rm
um caminho um pouco 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 +++
...
O sistema chama unlink()
e unlinkat()
é essencialmente o mesmo, exceto pelas diferenças descritas nesta página de manual: http://linux.die.net/man/2/unlinkat .
A chamada do sistema unlinkat () opera exatamente da mesma maneira que unlink (2) ou rmdir (2) (dependendo de os sinalizadores incluírem ou não o sinalizador AT_REMOVEDIR), exceto pelas diferenças descritas nesta página de manual.
Se o nome do caminho fornecido no nome do caminho for relativo, será interpretado em relação ao diretório referido pelo descritor de arquivo dirfd (em vez de relativo ao diretório de trabalho atual do processo de chamada, como é feito por unlink (2) e rmdir (2) ) para um nome de caminho relativo).
Se o nome do caminho fornecido no nome do caminho for relativo e dirfd for o valor especial AT_FDCWD, o nome do caminho será interpretado em relação ao diretório de trabalho atual do processo de chamada (como unlink (2) e rmdir (2)).
Se o nome do caminho fornecido no nome do caminho for absoluto, o dirfd será ignorado.
AT_FDCWD
, efetivamente não há diferença entre unlink
e unlinkat
.
POSIX especifica que o unlink
utilitário chama a unlink
função da biblioteca C e nada mais. Não precisa de opção. Se você passar um nome de caminho válido para algo que não é um diretório e se tiver permissões de gravação no diretório em que esse objeto mora, ele unlink
será removido.
rm
é um comando tradicional do Unix que possui algumas outras funcionalidades e não é um superconjunto unlink
(veja abaixo).
Em primeiro lugar, 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 a sua capacidade de removê-lo: as permissões diretamente são!), No rm
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 é frequentemente explorado em Makefiles ( clean: @rm -f $(OBJS) ...
), portanto make clean
não falha quando não há nada a remover.
Em segundo lugar, rm
tem a -i
opção de confirmar interativamente a exclusão.
Em terceiro lugar, rm
é necessário -r
remover recursivamente um diretório, o que unlink
não é necessário, pois a função da biblioteca C não faz isso.
O unlink
utilitário não é exatamente um despojado rm
. Ele executa um subconjunto do que rm
faz, mas possui semântica que é uma combinação de rm
with -f
e rm without -f
.
Suponha que você queira apenas remover um arquivo comum, independentemente de quais sejam 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
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 unlink
semântica pura do Unix : "faça esta entrada de diretório desaparecer se as permissões de diretório permitirem" .
unlink
vez de apenas descrever as diferenças.
Com um único arquivo, rm e unlink fazem a mesma tarefa, remova o arquivo. Conforme definido pelo POSIX, rm
e unlink
ambos chamam para desvincular () a chamada do sistema.
No GNU rm
, ele chama a chamada do sistema unlinkat () , que é equivalente à função unlink()
ou rmdir () , exceto no caso em que path especifica um caminho relativo.
Nota
Em alguns sistemas, unlink
também é possível remover o diretório Pelo menos no sistema GNU, unlink
nunca pode excluir o nome de um diretório.