Qual é o motivo para o rmdir (1) e o rm (1) coexistirem?

17

Eu uso BSD e Linux todos os dias, nunca tive uma circunstância em que devo usar rmdir (1) em vez de rm (1). Qual é o propósito da existência de rmdir?

Howard
fonte
2
OT, mas, FWIW, isso mostra um uso interessante (e diferente): cyberciti.biz/faq/linux-unix-remove-directory
pst

Respostas:

27

A principal razão é provavelmente histórica. De volta aos velhos, velhos tempos, não há foram rmdir(2)e mkdir(2)chamadas de sistema (estamos discutindo 7ª Edição UNIX ™ aqui), e rmdir(1)foi (por necessidade) um programa SUID root que usou a unlink(2)chamada de sistema para remover diretórios.

Os manuais da 7ª edição do UNIX estão disponíveis online em http://cm.bell-labs.com/7thEdMan (última verificação em 23-04-2017); Eles também estão disponíveis em http://plan9.bell-labs.com/7thEdMan (última verificação em 23/04/2017). Também parece haver pelo menos uma fonte alternativa online - http://wolfram.schneider.org/bsd/7thEdManVol2/ - para os artigos do Volume 2, com um link para o site do FreeBSD para os comandos e chamadas do sistema no Volume 1. .

O rmcomando (um programa regular não SUID) chamou o rmdir(1)comando para remover diretórios vazios. Não poderia fazer isso sozinho; que exigiam privilégios de root. Portanto, o rmdir(1)comando (veja aqui o código fonte no Unix V7) existia para remover diretórios vazios e o rmcomando não removeu os diretórios vazios.

Para usar rmpara remover diretórios, você deve dar a -ropção

Há também um argumento de simetria. Você precisa de um comando mkdir(1)para criar diretórios; parece razoável ter um comando rmdir(1)para desfazer o que mkdir(1)fez. Além disso, são (atualmente) simples exercitadores das chamadas the rmdir(2)e mkdir(2)system - sim, na 7ª Edição UNIX, mkdir(1)também era um programa raiz SUID, usando a mknod(2)chamada para criar um nó de diretório e a link(2)chamada para criar as entradas .e ..no diretório .

Jonathan Leffler
fonte
aha! tudo isso faz sentido, ótimo!
2
Agradável. Acabei de verificar uma cópia do 3BSD que tenho aqui e também não há documentação para um syscall do rmdir, e o rmdir (1) ainda é implementado usando o unlink.
Andy Ross
4
Uma desvantagem importante do sistema mknod + link and unlink foi que a criação de um diretório não era uma operação atômica; portanto, você pode acabar com um diretório parcialmente completo. Havia muitos programas criados para verificar os sistemas de arquivos quanto às inconsistências que surgiram; fsck(1)é o único que sobreviveu.
Jonathan Leffler
@ Jonathan, trazendo de volta memórias do Xenix naquele. Que nojo! Sim, coisas muito ruins podem acontecer.
Fiasco Labs
6

"rm" não funciona em diretórios. Você precisa usar rmdir ou especificar a opção -r para uma exclusão recursiva. A razão é histórica: unlinke rmdirsão chamadas de sistema separadas e tem sido desde os primeiros dias de Unix.

Andy Ross
fonte
4
Um efeito colateral feliz é que você tem um pouco menos probabilidade de excluir acidentalmente um diretório quando pretende remover apenas um arquivo.
Obrigado. Notei que "rm -r" e "rmdir" têm a mesma quantidade de pressionamentos de tecla. O rmdir existe puramente por razões históricas (.. sendo compatível com programas Unix de décadas)?
2
Na verdade, nos primeiros dias do Unix, rmdir(2)nem mkdir(2)existia nem como uma chamada de sistema; o usuário rootpode usar a mknod(2)chamada para criar um nó de diretório e a link(2)chamada para criar as entradas .e ..no diretório; e rootpoderia usar a unlink(2)chamada para remover as entradas do diretório.
Jonathan Leffler
3

O rmdir também remove apenas diretórios vazios . Se você deseja ter certeza de que não exclui nenhum arquivo adicional em um diretório, rmdiré mais seguro do que rm -r(exceto se você aliasar rm de forma que sempre precise confirmar o que excluir, por exemplo, alias rm='rm -i'em ~ / .bashrc ou o que estiver usando )

Simon A. Eugster
fonte
1

Além disso, rmdirfacilita a remoção de diretórios vazios com expressões ocultas (curinga). Por exemplo, para remover todos os diretórios vazios /tmpsem tocar em nenhum arquivo ou diretório com conteúdo:

cd /tmp ; rmdir *
Pat
fonte
Considere usar rmdir /tmp/*. Se o /tmpdiretório for realmente grande, isso pode ficar sem espaço para argumentos um pouco mais rápido devido aos cinco caracteres extras por nome, mas não requer que cdvocê se mova pela hierarquia de diretórios. Também vale rmdir /tmp/* 2>/dev/nulla pena considerar evitar ver mensagens de erro (normalmente haverá muitas e quase todas serão irrelevantes para essa tarefa em mãos).
precisa