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.
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.
"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):
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.
mkdir -p foo/{bar,baz}/zoo/andsoforth
. ¡Muy útil!mkdir
solo 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.Respuestas:
fuente
mkdir -p
no es multiplataforma, no funciona en cada caparazónmkdir -p
se especifica en POSIX , que es lo más parecido a ser totalmente portátil. ¿Qué mejor esperas en un script de shell?Usar
mkdir -p
es una forma simple para la mayoría de los sistemas operativos modernos:Sin embargo,
mkdir -p
no se recomienda en muchos manuales. Lea la documentación de GNUmake
yautoconf
sobre los problemas con el usomkdir -p
:Los sistemas de instalación y configuración multiplataforma tienen sus propias alternativas
mkdir -p
seguras .CMake para usar en la línea de comandos de shell:
Autoconf para usar en script con preprocesamiento:
o:
Pero estas soluciones requieren
cmake
oautoconf
(M4
) herramientas para ser instaladas (y posible preprocesamiento)También puede usar el
install-sh
script con la-d
opción:Este script es utilizado por
autoconf
yautomake
project. Creo que debe ser la solución más segura.En ese momento estaba buscando una solución multiplataforma para estándar
/bin/sh
sin 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 :Este script se puede usar para sistemas antiguos, donde la opción
-p
paramkdir
está ausente.sed
versión multiplataforma basada endirname
se agregó al código. Funciona de una manera similar adirname
(corregir con ruta/
, rutas con solo nombre base, rutas con seguimiento/
, rutas con y sin seguimiento\n
s). 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 1
atest -d "$1" || { mkdir "$1" || return 1; }
porquemkdir
termina con un error si la ruta existe y esta verificación es necesaria para las rutas que contienen construcciones comoaaa\.
(Siaaa
no existe, la versión anterior creaaaa
y 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
mkdir -p
serían demasiado antiguos (y estamos hablando de al menos un par de décadas) para tener unaprintf
utilidad o soporte--
para marcar el final de las opciones.cdirname
daría la respuesta equivocada parafoo/bar//
, o nombres de directorio que contiene caracteres de nueva línea, o caracteres no válidos en la localización actual.printf
es seguro en los sistemas POSIX. Soporte de sistemas POSIXmkdir -p
.mkdir -p
POSIX 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.printf
Primero apareció como unksh
incorporado, creo, y fue especificado por POSIX más tarde quemkdir -p
. Algunos shells POSIX (como pdksh o yash) aún no tienenprintf
incorporado.Opción
-p
al mandomkdir
hace p directorios Arent según sea necesario (sin error si existente):Otra forma es, por ejemplo, usar
&&
(error si existe la carpeta especificada):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.
fuente
Esto debería hacerlo.
fuente