Usarmkdir -p
es una forma simple para la mayoría de los sistemas operativos modernos:
mkdir -p foo/bar/zoo/andsoforth
Sin embargo, mkdir -p
no se recomienda en muchos manuales. Lea la documentación de GNU make
y autoconf
sobre 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 cmake
o autoconf
( M4
) herramientas para ser instaladas (y posible preprocesamiento)
También puede usar el install-sh
script con la -d
opción:
install-sh -d foo/bar/zoo/andsoforth
Este script es utilizado por autoconf
y automake
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 :
#! /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 -p
para mkdir
está ausente.
sed
versión multiplataforma basada en dirname
se 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 \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
a test -d "$1" || { mkdir "$1" || return 1; }
porque mkdir
termina con un error si la ruta existe y esta verificación es necesaria para las rutas que contienen construcciones como aaa\.
(Si aaa
no existe, la versión anterior crea aaa
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.