¿Por qué mkdir no tiene el indicador -p establecido de forma predeterminada para permitir la creación de directorios anidados?

11

No veo ninguna razón por la cual el -pindicador mkdirno debería establecerse de forma predeterminada.

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

Es un comando no destructivo por lo que puedo ver. ¿Me he perdido algo importante sobre cómo funciona esto?

En segundo lugar, ¿hay una manera fácil de hacer que este sea el comportamiento predeterminado de mkdir?

Treffynnon
fuente
2
poner esto en tu .bashrc: alias mkdir="mkdir -p".
Kevin
Después de toda la discusión, he decidido ir con un alias demkdp
Treffynnon

Respuestas:

6

Esta es una característica opcional, que no siempre se desea, especialmente en los scripts. Considere los siguientes inconvenientes en caso de scripts:

  • No se informa el hecho de que el directorio ya existe: si se supone que un script coloca algunos archivos en un directorio recién creado y ese directorio ya existe y contiene archivos, el script puede causar muchos problemas. (Será difícil filtrar más tarde los archivos que el script colocó allí).
  • Por otro lado, lo anterior, algunas secuencias de comandos (o parte de ellas) pueden depender de una estructura de directorio creada anteriormente (posiblemente por otro paquete / secuencia de comandos). Por ejemplo, una secuencia de comandos de instalación del paquete puede necesitar colocar bibliotecas en un subdirectorio /usr/local/lib/GreatSoftware/ImportantPartOfIt, pero las bibliotecas dependen de / link to stuff under /usr/local/lib/GreatSoftware. Si esto falta, la secuencia de comandos no debe continuar.

El comportamiento genérico de lo mkdirhace fácil y natural, ya que tales situaciones se informan y pueden detectarse de inmediato.


Puedes crear un alias si quieres usarlo siempre mkdir -pen tus shells:

alias mkdir='mkdir -p'

(Esto debería ir a su .bashrcconfiguración o la configuración que utilice su shell).

rozcietrzewiacz
fuente
1
No sugeriría alias un comando estándar para que se comporte de una manera no estándar. Eso haría que los guiones no fueran portátiles y podría confundir a los lectores. Crear un nuevo alias o función, como alias mkdp="mkdir -p"sería más aconsejable.
jlliagre
2
@jlliagre No, no afectaría los scripts. Los alias definidos localmente en .bashrcno (normalmente) afectan sus entornos.
rozcietrzewiacz
De hecho, pero perdiste mi punto. Aliasing un comando estándar para cambiar su comportamiento, incluso para su propio uso, no es una práctica recomendada. El peor ejemplo es el omnipresente alias rm='rm -i'.
jlliagre
1
@jlliagre ¿No recomendado por quién? ;) Pero sí, estoy de acuerdo, prefiero usar un alias diferente, pero por razones prácticas, no ideológicas. Tampoco creo que el rm -ialias sea siempre malo, aunque podría conducir a malos hábitos. Ciertamente, no todos los alias de comando son igualmente buenos / malos, considérelo ls="ls --color=auto"o, ssh="TERM=xterm ssh"por ejemplo.
rozcietrzewiacz
No hay nada ideológico en mi recomendación. El rm alias es indirectamente responsable de muchos archivos perdidos (he conocido muchas víctimas de este alias). Sospechaba que el mkdir tenía, en un grado mucho menor, efectos secundarios no deseados. Por supuesto, no estoy en contra de los cambios cosméticos, no de comportamiento, como sus ejemplos ssh y ls.
jlliagre
16

Por supuesto, uno podría argumentar que la creación del directorio principal debería ser la predeterminada y alguna opción de verificación podría usarse para evitar la creación del directorio si el principal no existe.

Pero la razón por la cual es al revés es solo historia. La versión básica de mkdir no creó directorios principales. Esta es la razón por la cual las distribuciones X11 llegaron junto con un comando llamado mkdirhier que pudo cumplir esta tarea: verifique si existen los directorios principales y créelos si es necesario.

Más tarde, esta funcionalidad se agregó al comando mkdir en muchas versiones de UNIX (no sé si actualmente está en el estándar POSIX). Para mantener la compatibilidad con esta característica se puso a disposición mediante la activación de una bandera opción: -p.

¿Por qué es malo tenerlo activado de forma predeterminada? Los scripts pueden confiar en que mkdir falla si el directorio padre no existe. Especialmente como usuario root , podría ser peligroso crear árboles de directorios por defecto.

Ejemplo:

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

En este ejemplo, el directorio se crearía y la copia de seguridad se realizaría incluso si el sistema de archivos /backupno está montado y el padre /backup/$(uname -n)no existe si el valor predeterminado sería al revés.

Regla de oro: es una buena práctica no cambiar el comportamiento predeterminado de ninguna herramienta. Si lo desea, proporcione opciones para permitir cambiar el comportamiento predeterminado.

ktf
fuente
2
Me gusta el ejemplo de montaje que has usado aquí. No había pensado en ese escenario en particular.
Treffynnon
1
Las opciones -p (y -m) fueron introducidas por System V en 1983. Ambas son definitivamente parte del estándar POSIX.
jlliagre
4

Creo que esta es una filosofía. El comando bare mkdir (1) (sin opciones) representa la llamada al sistema mkdir (2) , proporcionando su funcionalidad en shell, sin hacer nada más o menos.

ern0
fuente
4

Al principio , solo existía el mkdircomando desnudo . De acuerdo con los principios de diseño de Unix, este comando simple realizó una tarea simple: crear un directorio.

Más tarde, mkdiradquirió una -popción para manejar un caso de uso común en el que la persona que llama desea crear cero, uno o más directorios para garantizar que exista una ruta en particular. Esto no se convirtió en la operación predeterminada por varias razones. Primero, no todos los sistemas tenían esta característica más compleja, y requerir la -popción significaba que los scripts que la usaban obtendrían un mensaje de error razonable (algo así mkdir: invalid option -z) en lugar de fallar extrañamente en la creación de directorios ocasionalmente. En segundo lugar, y lo más importante, el comportamiento de mkdir -pno es un reemplazo compatible mkdiren todos los casos.

En particular, en la mayoría de los sistemas de archivos, mkdires una operación atómica . Si se ejecuta un programa mkdir playgroundy el comando tiene éxito, el programa sabe que creó el playgrounddirectorio. Esto permite que el programa trate el nuevo directorio como su área de juegos exclusiva: si otra instancia del mismo programa se ejecuta simultáneamente, su llamada a mkdir playgroundfallará. Obviamente, esta propiedad no se proporciona mkdir -pya que permite que exista el argumento.

Si mkdir -phubiera existido desde el principio, podría haberse convertido en el modo predeterminado, con algo así como mkdir -apara el comando de creación de un solo directorio. Pero eso no habría seguido la filosofía habitual de diseño de Unix: la mayoría de las utilidades básicas son envoltorios simples alrededor de las primitivas subyacentes, con un comportamiento más sofisticado (como crear múltiples directorios de una vez) que requieren opciones sofisticadas.

Gilles 'SO- deja de ser malvado'
fuente
2

Para mí, el problema es que el comportamiento de la opción -p si fuera el predeterminado es esencialmente un efecto secundario. Agrega complejidad a un comando al hacer algo adicional a lo que le pidió que hiciera. Es una cosa invisible más para tener que recordar. Una de las reglas básicas de la práctica de programación de sonido es evitar los efectos secundarios.

Los lenguajes de programación modernos son tan potentes que es relativamente fácil construir cualquier comando complejo que pueda necesitar a partir de las primitivas que proporciona un lenguaje. Hacerlo implica tomar una decisión consciente sobre qué comportamiento se requiere y también deja un registro concreto y visible de lo que se ha hecho.

Joe
fuente