Por que o mkdir não tem o sinalizador -p definido por padrão para permitir a criação de diretório aninhado?

11

Não vejo razão para que o -psinalizador mkdirativado não seja definido por padrão.

  -p, --parents     no error if existing, make parent directories as needed

É um comando não destrutivo do que posso ver. Perdi algo importante sobre o modo como isso funciona?

Em segundo lugar, existe uma maneira fácil de conseguir que esse seja o comportamento padrão de mkdir?

Treffynnon
fonte
2
colocar isso em seu .bashrc: alias mkdir="mkdir -p".
31411 Kevin
Depois de toda a discussão, decidi usar um pseudônimo demkdp
Treffynnon 7/11/11

Respostas:

6

Esse é um recurso opcional, que nem sempre é desejado - especialmente em scripts. Considere as seguintes desvantagens no caso de scripts:

  • O fato de o diretório já existir não é relatado: se um script deve colocar alguns arquivos em um diretório recém-criado e esse diretório já existe e contém arquivos, o script pode causar muita confusão. (É trabalhoso filtrar posteriormente os arquivos que foram colocados lá pelo script.)
  • Por outro lado, alguns scripts (ou parte deles) podem depender de uma estrutura de diretórios criada anteriormente (possivelmente por outro pacote / script). Por exemplo, um script de instalação de pacote pode precisar colocar bibliotecas em um subdiretório /usr/local/lib/GreatSoftware/ImportantPartOfIt, mas as bibliotecas dependem do / link para o material abaixo /usr/local/lib/GreatSoftware. Se isso estiver faltando, o script não deve continuar.

O comportamento genérico de mkdirtorna mais fácil e natural, pois essas situações são relatadas e podem ser detectadas imediatamente.


Você pode criar um alias para isso, se quiser sempre usar mkdir -pem seus shells:

alias mkdir='mkdir -p'

(Isso deve ir para o seu .bashrcou qualquer configuração que seu shell use.)

rozcietrzewiacz
fonte
1
Eu não sugeriria um apelido de comando padrão para fazê-lo se comportar de maneira não-padrão. Isso tornaria os scripts não portáteis e pode confundir os leitores. Criar um novo alias ou função, como alias mkdp="mkdir -p"seria mais aconselhável.
Jlliagre 31/10/11
2
@ jlliagre Não, isso não afetaria os scripts. Os aliases definidos localmente em .bashrc(normalmente) não afetam seus ambientes.
rozcietrzewiacz 31/10
Na verdade, mas você perdeu o meu ponto. Aliasing um comando padrão para alterar seu comportamento, mesmo para seu próprio uso, não é uma prática recomendada. O pior exemplo é o onipresente alias rm='rm -i'.
Jlliagre 31/10/11
1
@jlliagre Não recomendado por quem? ;) Mas sim, eu concordo, eu prefiro usar um apelido diferente - mas por razões práticas, não ideológicas. Também não acho que rm -ialias seja sempre ruim - embora possa levar a maus hábitos. Certamente nem todos os apelidos de comando são igualmente bons / ruins - considere ls="ls --color=auto"ou ssh="TERM=xterm ssh"por exemplo.
rozcietrzewiacz
Não há nada ideológico na minha recomendação. O alias rm é indiretamente responsável por muitos arquivos perdidos (eu conheci muitas vítimas desse alias). Eu suspeitava que o mkdir tivesse, em muito menor grau, efeitos colaterais indesejados. É claro que não sou contra mudanças cosméticas, nem comportamentais, como os exemplos ssh e ls.
Jlliagre 31/10/11
16

Obviamente, pode-se argumentar que a criação do diretório pai deve ser o padrão e alguma opção de verificação pode ser usada para impedir a criação do diretório se o pai não existir.

Mas a razão pela qual é o contrário é apenas história. A versão básica do mkdir não criou diretórios pai. É por isso que as distribuições X11 vieram com um comando chamado mkdirhier, capaz de executar esta tarefa: verifique se os diretórios pai existem e crie-os, se necessário.

Posteriormente, essa funcionalidade foi adicionada ao comando mkdir em muitas versões do UNIX (não sei se ele está atualmente no padrão POSIX). Para manter a compatibilidade esse recurso foi disponibilizado, rodando em uma bandeira opção: -p.

Por que é ruim ativá-lo por padrão? Os scripts podem confiar na falha do mkdir se o diretório pai não existir. Especialmente como usuário root , pode ser perigoso criar árvores de diretório por padrão.

Exemplo:

 if mkdir /backup/$(uname -n)/$(date +%Y%m%d)
  then
    perform_backup ...

Neste exemplo, o diretório seria criado e o backup executado mesmo se o sistema de arquivos /backupnão estiver montado e o pai /backup/$(uname -n)não existir se o padrão for o contrário.

Regra geral: é uma boa prática não alterar o comportamento padrão de nenhuma ferramenta. Se desejado, forneça opções para permitir a alteração do comportamento padrão.

ktf
fonte
2
Eu gosto do exemplo de montagem que você usou aqui. Eu não tinha pensado naquele cenário em particular.
Treffynnon
1
As opções -p (e -m) foram introduzidas pelo Sistema V em 1983. Ambas são definitivamente parte do padrão POSIX.
Jlliagre 31/10/11
4

Eu acho que isso é meio que filosofia. O comando bare mkdir (1) (sem opções) representa a chamada do sistema mkdir (2) , fornecendo sua funcionalidade no shell, sem fazer nada mais ou menos.

ern0
fonte
4

No começo , havia apenas o mkdircomando nu . De acordo com os princípios de design do Unix, este comando simples executou uma tarefa simples: criar um diretório.

Posteriormente, mkdiradquiriu uma -popção para lidar com um caso de uso comum em que o chamador deseja criar zero, um ou mais diretórios para garantir a existência de um caminho específico. Isso não foi tornado a operação padrão por vários motivos. Primeiro, nem todos os sistemas tinham esse recurso mais complexo, e exigir a -popção significava que os scripts que o usassem receberiam uma mensagem de erro razoável (algo como mkdir: invalid option -z) ao invés de estranhamente falhar ao criar diretórios ocasionalmente. Segundo, e mais importante, o comportamento de mkdir -pnão é uma substituição compatível mkdirem todos os casos.

Em particular, na maioria dos sistemas de arquivos, mkdiré uma operação atômica . Se um programa for executado mkdir playgrounde o comando for bem-sucedido, o programa sabe que criou o playgrounddiretório. Isso permite que o programa trate o novo diretório como seu playground exclusivo: se outra instância do mesmo programa estiver sendo executada simultaneamente, sua chamada para mkdir playgroundfalhará. Obviamente, essa propriedade não é fornecida, mkdir -ppois permite que o argumento exista.

Se mkdir -pexistisse desde o início, poderia ter sido feito no modo padrão, com algo parecido mkdir -acom o comando de criação de diretório único. Mas isso não teria seguido a filosofia usual de design do Unix: os utilitários mais básicos são wrappers simples em torno das primitivas subjacentes, com um comportamento mais sofisticado (como criar vários diretórios de uma só vez) exigindo opções sofisticadas.

Gilles 'SO- parar de ser mau'
fonte
2

Para mim, o problema é que o comportamento da opção -p, se fosse o padrão, é essencialmente um efeito colateral. Ele adiciona complexidade a um comando, fazendo algo adicional ao que você pediu. É mais uma coisa invisível a ser lembrada. Uma das regras básicas da boa prática de programação é evitar efeitos colaterais.

As linguagens de programação modernas são tão poderosas que é relativamente fácil criar qualquer comando complexo que você possa precisar a partir das primitivas que uma linguagem fornece. Fazer isso envolve tomar uma decisão consciente sobre qual comportamento é necessário e também deixa um registro concreto e visível do que foi feito.

Joe
fonte