mkdir recursivo

307

¿Hay un comando de Linux que estoy pasando por alto que hace posible hacer algo en la línea de: (pseudo)

$ mkdir -R foo/bar/zoo/andsoforth

¿O no hay otra alternativa que hacer los directorios uno a la vez?

Braiam
fuente
1
Es curioso, estaba mirando esa página, pero pasé por alto al "padre" porque pensaba en ellos como niños (de izquierda a derecha).
18
Protip: en algunos proyectiles incluso puedes hacer mkdir -p foo/{bar,baz}/zoo/andsoforth. ¡Muy útil!
Aaron Copley
1
Personalmente, también pasé por alto a "padre" en la página de manual porque, bueno, siento que la bandera debería ser "-r" para "recursivo", o al menos, debería haber un alias para eso ya que mkdirsolo tiene 6 banderas documentadas en total. Demonios, siento que el comando debería crear directorios de forma recursiva por defecto, y si no quieres esto, entonces deberías especificarlo de manera explícita.
jbowman
1
stackoverflow.com/questions/1731767/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

513
$ mkdir -p foo/bar/zoo/andsoforth
EEAA
fuente
93
FYI the -p significa "padres"
carl crott
14
Podrían haber hecho -r en su lugar, como cualquier otro comando, es imposible recordar parámetros específicos para cada comando de Linux
Vedmant
2
Pero mkdir -pno es multiplataforma, no funciona en cada caparazón
Роман Коптев
99
@ РоманКоптев, mkdir -pse especifica en POSIX , que es lo más parecido a ser totalmente portátil. ¿Qué mejor esperas en un script de shell?
Comodín el
55
@StephanBijzitter Sí, esto es unix.se, no unixandwindows.se. :)
EEAA
16

Usarmkdir -p es una forma simple para la mayoría de los sistemas operativos modernos:

mkdir -p foo/bar/zoo/andsoforth

Sin embargo, mkdir -pno se recomienda en muchos manuales. Lea la documentación de GNU makey autoconfsobre los problemas con el uso mkdir -p:

Los sistemas de instalación y configuración multiplataforma tienen sus propias alternativasmkdir -p seguras .

CMake para usar en la línea de comandos de shell:

 cmake -E make_directory foo/bar/zoo/andsoforth

Autoconf para usar en script con preprocesamiento:

AS_MKDIR_P(foo/bar/zoo/andsoforth)

o:

AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)

Pero estas soluciones requieren cmakeo autoconf( M4) herramientas para ser instaladas (y posible preprocesamiento)

También puede usar el install-shscript con la -dopción:

install-sh -d foo/bar/zoo/andsoforth

Este script es utilizado por autoconfy automakeproject. Creo que debe ser la solución más segura.

En ese momento estaba buscando una solución multiplataforma para estándar /bin/shsin dependencias, pero no encontré una. Por lo tanto, escribí el siguiente script que puede no ser ideal, pero creo que cumple con la mayoría de los requisitos multiplataforma :

#! /bin/sh

cdirname() # cross platform alternative for 'dirname'
{
  # $1 - path
  test $# -eq 1 || { echo "Procedure 'cdirname' must have only one parameter. Scripting error."; exit 1; }
  echo "$1" | sed -n -e '1p' | sed  -e 's#//*#/#g' -e 's#\(.\)/$#\1#' -e 's#^[^/]*$#.#' -e 's#\(.\)/[^/]*$#\1#' -
}

mkd() # cross platform alternative for 'mkdir -p'
{
  # $1 - directory to create
  test $# -eq 1 || { echo "Function 'mkd' can create only one directory (with it's parent directories)."; exit 1; }
  test -d "$1"  && return 0
  test -d "$(cdirname "$1")" || { mkd "$(cdirname "$1")" || return 1; }
  test -d "$1" || { mkdir "$1" || return 1; }
  return 0
}

Este script se puede usar para sistemas antiguos, donde la opción -ppara mkdirestá ausente.

sedversión multiplataforma basada en dirnamese agregó al código. Funciona de una manera similar a dirname(corregir con ruta /, rutas con solo nombre base, rutas con seguimiento /, rutas con y sin seguimiento \ns). Esta función no puede funcionar correctamente si la ruta tiene líneas nuevas o algunos caracteres no válidos para la configuración regional actual. También reemplaza cualquier combinación de /( //, ///) con un solo/

La línea cambiada mkdir "$1" || return 1a test -d "$1" || { mkdir "$1" || return 1; }porque mkdirtermina con un error si la ruta existe y esta verificación es necesaria para las rutas que contienen construcciones como aaa\.(Si aaano existe, la versión anterior crea aaay luego intenta crearla nuevamente).

Esta versión de mkd no genera un error si la ruta ya existe (pero aún tiene la posibilidad de generar dicho error en ejecución paralela) y no puede obtener varios directorios en la línea de comandos.

Роман Коптев
fuente
44
"mkdir -p" está definido por posix. ¿Qué variantes de Unix o similares a Unix no lo admiten? (y no debería ser un shell incorporado, aunque supongo que no hay ninguna razón para que no sea así). pubs.opengroup.org/onlinepubs/9699919799/utilities/mkdir.html
Tim B
55
Parte de la información en esa página tiene solo 15 años. Algunos son mayores.
Thomas Dickey
77
Los sistemas que no admitirían mkdir -pserían demasiado antiguos (y estamos hablando de al menos un par de décadas) para tener una printfutilidad o soporte --para marcar el final de las opciones.
Stéphane Chazelas
2
Su cdirnamedaría la respuesta equivocada para foo/bar//, o nombres de directorio que contiene caracteres de nueva línea, o caracteres no válidos en la localización actual.
Stéphane Chazelas
2
printfes seguro en los sistemas POSIX. Soporte de sistemas POSIX mkdir -p. mkdir -pPOSIX lo ha especificado durante décadas. --comenzó a difundirse en los sistemas AT&T a partir de SysIII a principios de mediados de los 80. printfPrimero apareció como un kshincorporado, creo, y fue especificado por POSIX más tarde que mkdir -p. Algunos shells POSIX (como pdksh o yash) aún no tienen printfincorporado.
Stéphane Chazelas
0

Opción -pal mando mkdirhace p directorios Arent según sea necesario (sin error si existente):

mkdir -p foo/bar/zoo/andsoforth

Otra forma es, por ejemplo, usar &&(error si existe la carpeta especificada):

mkdir foo && mkdir foo/bar && mkdir foo/bar/zoo && mkdir foo/bar/zoo/andsoforth

El operador de encadenamiento &&se usa para encadenar comandos, de modo que el siguiente comando se ejecuta si y solo si el comando anterior salió sin errores.

Por supuesto, la primera forma es mejor.

simhumileco
fuente
-3
mkdir foo foo/bar foo/bar/zoo/ foo/bar/zoo/andsofort.

Esto debería hacerlo.

Kanchan Kumar
fuente