Por que o mkdir não possui o sinalizador -p configurado por padrão para permitir a criação do diretório aninhado?

11

Não vejo motivo para que o sinal -p em mkdir 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 eu posso ver. Eu perdi algo importante sobre como isso funciona?

Em segundo lugar, há uma maneira fácil de fazer com que esse seja o comportamento padrão de mkdir ?

    
por Treffynnon 31.10.2011 / 11:36

5 respostas

6

Este é 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á existir e contiver arquivos, o script pode causar muita confusão. (Será difícil filtrar posteriormente os arquivos que foram colocados lá pelo script).
  • Por outro lado, algum script (ou parte dele) pode depender de uma estrutura de diretório 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 de / link para coisas em /usr/local/lib/GreatSoftware . Se isso estiver faltando, o script não deve continuar.

O comportamento genérico de mkdir torna isso fácil e natural, pois essas situações são relatadas e podem ser capturadas imediatamente.

Você pode criar um alias para ele se quiser sempre usar mkdir -p em seus shells:

alias mkdir='mkdir -p'

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

    
por 31.10.2011 / 11:59
16

É claro que alguém poderia argumentar que a criação do diretório pai deveria ser o padrão e que alguma opção de verificação poderia 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 criava diretórios pai. É por isso que as distribuições X11 vieram junto com um comando chamado mkdirhier que foi capaz de realizar esta tarefa: verificar se os diretórios-pai existem e criá-los se necessário.

Mais tarde, essa funcionalidade foi adicionada ao comando mkdir em muitas versões do UNIX (não sei se está no padrão POSIX atualmente). Para manter a compatibilidade, esse recurso foi disponibilizado ao ativar um sinalizador de opção: -p .

Por que é ruim ativá-lo por padrão? Scripts podem depender do mkdir falhando se o diretório pai não existir. Especialmente como usuário root , pode ser perigoso criar árvores de diretórios 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 realizado até mesmo é o sistema de arquivos /backup não está montado e o pai /backup/$(uname -n) não existe se o padrão for o contrário.

Regra geral: é recomendável não alterar o comportamento padrão de qualquer ferramenta. Se desejar, forneça opções para permitir alterar o comportamento padrão.

    
por 31.10.2011 / 12:42
4

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

    
por 31.10.2011 / 17:01
4

No início , havia apenas o comando mkdir . De acordo com os princípios de design do Unix, esse comando simples executou uma tarefa simples: criar um diretório.

Mais tarde, mkdir adquiriu uma opção -p para lidar com um caso de uso comum em que o chamador deseja criar zero, um ou mais diretórios para garantir que um determinado caminho exista. Isso não foi feito a operação padrão por vários motivos. Primeiro, nem todos os sistemas tinham esse recurso mais complexo, e exigir a opção -p significava que os scripts que o usavam receberiam uma mensagem de erro razoável (algo como mkdir: invalid option -z ) em vez de criarem diretórios ocasionalmente. Segundo, e mais importante, o comportamento de mkdir -p não é uma substituição compatível de mkdir em todos os casos.

Em particular, na maioria dos sistemas de arquivos, mkdir é uma operação atômica . Se um programa executar mkdir playground e o comando for bem-sucedido, o programa saberá que criou o diretório playground . 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 playground falhará. Esta propriedade obviamente não é fornecida por mkdir -p , pois permite que o argumento exista.

Se mkdir -p existisse desde o início, poderia ter sido feito o modo padrão, com algo como mkdir -a para o comando de criação de diretório único. Mas isso não teria seguido a filosofia de design usual do Unix: a maioria dos utilitários básicos são invólucros 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.

    
por 31.10.2011 / 23:54
2

Para mim, a questão é 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 para fazer. É mais uma coisa invisível para se lembrar. Uma das regras básicas da prática de programação de som é evitar efeitos colaterais.

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

    
por 05.11.2011 / 12:30