Perché mkdir non ha il flag -p impostato di default per consentire la creazione di directory nidificate?


11

Non vedo alcun motivo per cui la -pbandiera mkdirattivata non debba essere impostata per impostazione predefinita.

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

È un comando non distruttivo da quello che posso vedere. Ho perso qualcosa di importante nel modo in cui funziona?

In secondo luogo, esiste un modo semplice per ottenere che questo sia il comportamento predefinito di mkdir?


2
mettere questo nel vostro .bashrc: alias mkdir="mkdir -p".
Kevin,

Dopo tutta la discussione, ho deciso di seguire un alias dimkdp
Treffynnon,

Risposte:


6

Questa è una funzione opzionale, che non è sempre desiderata, specialmente negli script. Considerare i seguenti svantaggi in caso di script:

  • Il fatto che la directory esista già non viene riportato: se si suppone che uno script inserisca alcuni file in una directory appena creata e che tale directory esista già e contenga file, lo script può creare molti problemi. (Sarà difficile filtrare in seguito i file che sono stati collocati lì dallo script.)
  • D'altro canto, alcuni script (o parte di essi) possono dipendere da una struttura di directory creata in precedenza (possibilmente da altri pacchetti / script). Ad esempio, potrebbe essere necessario che uno script di installazione del pacchetto inserisca le librerie in un sottodir /usr/local/lib/GreatSoftware/ImportantPartOfIt, ma le librerie dipendono da / link alle cose sotto /usr/local/lib/GreatSoftware. Se questo manca, lo script non dovrebbe continuare.

Il comportamento generico di lo mkdirrende facile e naturale, poiché tali situazioni vengono segnalate e possono essere colte immediatamente.


Puoi creare un alias per questo se vuoi usare sempre mkdir -pnelle tue shell:

alias mkdir='mkdir -p'

(Questo dovrebbe andare al tuo .bashrco qualunque config usi la tua shell.)


1
Non consiglierei di alias un comando standard per farlo comportare in modo non standard. Ciò renderebbe gli script non portatili e potrebbe confondere i lettori. Creare un nuovo alias o funzione, come alias mkdp="mkdir -p"sarebbe più consigliabile.
jlliagre,

2
@jlliagre No, non influirebbe sugli script. Gli alias definiti localmente .bashrcnon influiscono (normalmente) sui loro ambienti.
rozcietrzewiacz,

Anzi, ma ti sei perso il punto. Alias ​​di un comando standard per modificarne il comportamento, anche per uso personale, non è una pratica consigliata. L'esempio peggiore è l'onnipresente alias rm='rm -i'.
jlliagre,

1
@jlliagre Non raccomandato da chi? ;) Sì, sono d'accordo, preferirei io stesso utilizzare un diverso alias - ma per ragioni pratiche, non ideologiche. Inoltre, non penso che l' rm -ialias sia sempre negativo, anche se potrebbe portare a cattive abitudini. Certamente non tutti gli alias di comando sono ugualmente buoni / cattivi - considerare ls="ls --color=auto"o ssh="TERM=xterm ssh"per esempio.
rozcietrzewiacz,

Non c'è nulla di ideologico nella mia raccomandazione. L'alias rm è indirettamente responsabile di molti file persi (ho incontrato molte vittime di questo alias). Sospettavo che quello di mkdir avesse, in misura molto minore, effetti collaterali indesiderati. Certo, non sono contrario ai cambiamenti cosmetici, non comportamentali, come i tuoi esempi di ssh e ls.
jlliagre,

16

Naturalmente si potrebbe sostenere che la creazione della directory padre dovrebbe essere l'impostazione predefinita e che alcune opzioni di controllo potrebbero essere utilizzate per impedire la creazione della directory se il padre non esiste.

Ma il motivo per cui è il contrario è solo la storia. La versione base di mkdir non ha creato le directory principali. Questo è il motivo per cui le distribuzioni X11 sono arrivate con un comando chiamato mkdirhier che è stato in grado di adempiere a questo compito: controllare se esistono le directory madri e crearle se necessario.

In seguito questa funzionalità è stata aggiunta al comando mkdir su molte versioni UNIX (non so se al giorno d'oggi sia nello standard POSIX). Per mantenere la compatibilità, questa funzione è stata resa disponibile attivando un flag di opzione:-p .

Perché è male averlo attivato per impostazione predefinita? Gli script possono fare affidamento sul fallimento di mkdir se la directory padre non esiste. Soprattutto come utente root potrebbe essere pericoloso creare alberi di directory di default.

Esempio:

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

In questo esempio la directory verrebbe creata e il backup eseguito anche se il filesystem /backupnon fosse montato e il genitore /backup/$(uname -n)non esisterebbe se il default fosse il contrario.

Regola empirica: è buona norma non modificare il comportamento predefinito di qualsiasi strumento. Se lo si desidera, fornire opzioni per consentire la modifica del comportamento predefinito.


2
Mi piace l'esempio di mount che hai usato qui. Non avevo pensato a quel particolare scenario.
Treffynnon,

1
Le opzioni -p (e -m) sono state introdotte da System V nel 1983. Entrambe fanno sicuramente parte dello standard POSIX.
jlliagre,

4

Penso che questa sia una specie di filosofia. Il comando bare mkdir (1) (senza opzioni) rappresenta la chiamata di sistema mkdir (2) , fornendo la sua funzionalità nella shell, senza fare nulla di più o di meno.


4

In principio , c'era solo la nuda mkdircomando. In conformità con i principi di progettazione di Unix, questo semplice comando ha svolto un semplice compito: creare una directory.

Successivamente, ha mkdiracquisito -pun'opzione per gestire un caso d'uso comune in cui il chiamante desidera creare zero, una o più directory per garantire l'esistenza di un determinato percorso. Questo non è stato reso l'operazione predefinita per diversi motivi. Innanzitutto, non tutti i sistemi avevano questa caratteristica più complessa e richiedere l' -popzione significava che gli script che la utilizzavano avrebbero ricevuto un ragionevole messaggio di errore (qualcosa del genere mkdir: invalid option -z) piuttosto che non riuscire a creare stranamente directory occasionalmente. In secondo luogo, e soprattutto, il comportamento di mkdir -pnon è una sostituzione compatibile dimkdir in tutti i casi.

In particolare, sulla maggior parte dei file system, mkdirè un'operazione atomica . Se un programma viene eseguito mkdir playgrounde il comando ha esito positivo, il programma sa che ha creato la playgrounddirectory. Ciò consente al programma di trattare la nuova directory come parco giochi esclusivo: se un'altra istanza dello stesso programma è in esecuzione contemporaneamente, la sua chiamata a mkdir playgroundfallirà. Questa proprietà non è ovviamente fornita da mkdir -ppoiché consente l'argomento.

Se mkdir -pfosse esistito dall'inizio, avrebbe potuto essere impostato come modalità predefinita, con qualcosa di simile mkdir -aal comando di creazione di directory singole. Ma ciò non avrebbe seguito la solita filosofia di progettazione Unix: la maggior parte delle utility di base sono semplici wrapper attorno alle primitive di base, con comportamenti più fantasiosi (come la creazione di più directory in una volta sola) che richiedono opzioni fantasiose.


2

Per me, il problema è che il comportamento dell'opzione -p se fosse il default è essenzialmente un effetto collaterale. Aggiunge complessità a un comando facendo qualcosa in più rispetto a ciò che gli hai chiesto di fare. È un'altra cosa invisibile da ricordare. Una delle regole di base della buona pratica di programmazione è quella di evitare effetti collaterali.

I moderni linguaggi di programmazione sono così potenti che è relativamente facile costruire qualsiasi comando complesso di cui potresti aver bisogno dalle primitive fornite da un linguaggio. Fare ciò implica prendere una decisione consapevole su quale comportamento è richiesto e lasciare anche una traccia concreta e visibile di ciò che è stato fatto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.