¿Cómo hacer mkdir solo si todavía no existe un directorio?


1989

Estoy escribiendo un script de shell para ejecutar bajo KornShell (ksh) en AIX. Me gustaría usar el mkdircomando para crear un directorio. Pero el directorio ya puede existir, en cuyo caso no quiero hacer nada. Por lo tanto, quiero probar para ver si el directorio no existe o suprimir el error "El archivo existe" que mkdiraparece cuando intenta crear un directorio existente.

¿Alguna idea sobre la mejor manera de hacer esto?

Respuestas:


3296

Prueba mkdir -p:

mkdir -p foo

Tenga en cuenta que esto también creará cualquier directorio intermedio que no exista; por ejemplo,

mkdir -p foo/bar/baz

creará directorios foo, foo/bary foo/bar/bazsi no existen.

Algunas implementaciones como GNU mkdirincluyen mkdir --parentsun alias más legible, pero esto no se especifica en POSIX / Single Unix Specification y no está disponible en muchas plataformas comunes como macOS, varios BSD y varios Unix comerciales, por lo que debe evitarse.

Si desea un error cuando los directorios principales no existen, y desea crear el directorio si no existe, entonces puede hacerlo testprimero para la existencia del directorio:

[ -d foo ] || mkdir foo

11
El ejemplo abreviado que utiliza es exactamente lo que no debe hacer. Está invirtiendo la lógica para ahorrar espacio de codificación, ¡pero debería usarlo! y && y tienen más sentido para quienes lo leen.
Mike Q

16
@AndreasLarsen Esta pregunta se trata mkdiren sistemas tipo Unix, no en Windows. -pse requiere para el cumplimiento de la especificación POSIX / Single Unix, por lo que cualquier cosa que intente cumplir con esas especificaciones será compatible -p. Windows es completamente diferente, a menos que use una capa de emulación POSIX como Cygwin o MSYS.
Brian Campbell

22
Descubrí algo interesante hoy mkdir -p, ¡puedes usar paréntesis! {}para crear un árbol de directorio "complejo" en un comando. Ver aquí: technosophos.com/2010/04/15/…
herve

12
@MikeQ Preferiría en ||lugar de &&porque toda la línea tiene el estado de salida correcto. Importante si su shell se ejecuta con errexito si esa línea es la última en una función, switch-case, lo que sea.
rudimeier

99
@herve Eso no tiene nada que ver con mkdir; el shell expande dicha expresión a una lista discreta de argumentos a los que se pasa mkdir.
chepner

177

Esto debería funcionar:

$ mkdir -p dir

o:

if [[ ! -e $dir ]]; then
    mkdir $dir
elif [[ ! -d $dir ]]; then
    echo "$dir already exists but is not a directory" 1>&2
fi

que creará el directorio si no existe, pero le advertirá si el nombre del directorio que está tratando de crear ya está en uso por algo que no sea un directorio.


No creo que haya un operador -d en korn, más bien -e se usa para ambos archivos / directorios y solo verifica la existencia. Además, todos devuelven 0 después del éxito, ¡así que! es redundante Corrígeme si estoy equivocado.
alkar

1
mal en ambos aspectos, AFAIK. las pruebas devuelven verdaderas en caso de éxito, y -d también existe (al menos en MacOS X)
Alnitak

55
Vale la pena mencionar que esto no es seguro para subprocesos. entre el momento en que verifica si el directorio existe y el momento en que intenta escribir, las cosas pueden cambiar.
Justin L.


74

Definir árboles de directorios complejos con un comando

mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}

sin error si existe, haga directorios principales según sea necesario
Fedir RYKHTIK

19
Tenga en cuenta que esto no es una característica en mkdirsí misma, sino el shell que ejecuta el comando. Se llama expansión de llaves: AFAIK, solo Bash, ksh, zsh y C shell lo admiten.
Daniel Kamil Kozar

3
Si tiene espacios alrededor de las comas, puede (obtendrá) un resultado inesperado. Tener cuidado.
Atlas7

1
@ Atlas7 declaró que necesitará escapar de los personajes que normalmente son parte de regex. (es decir, en lugar de usar folder name, debe usar folder\ name)
John Hamilton

1
Esta no es una respuesta; Este es un tema separado que sería más apropiado como comentario.
Chris Page

40

Si no desea mostrar ningún mensaje de error:

[ -d newdir ] || mkdir newdir

Si desea mostrar su propio mensaje de error:

[ -d newdir ] && echo "Directory Exists" || mkdir newdir

20

El viejo probado y verdadero

mkdir /tmp/qq >/dev/null 2>&1

hará lo que quiera sin ninguna de las condiciones de carrera que tienen muchas de las otras soluciones.

A veces las soluciones más simples (y más feas) son las mejores.


55
Esto fallará si "tmp" no existiera. ni te da ninguna confirmación.
Mike Q

15

mkdir foofunciona incluso si el directorio existe. Para que funcione solo si el directorio llamado "foo" no existe, intente usar la -pbandera.

Ejemplo:

mkdir -p foo

Esto creará el directorio llamado "foo" solo si no existe. :)


2
Como mencionó @BrianCampbell, esto también creará otros directorios en la ruta. Esto puede ser peligroso si, por ejemplo, un volumen se desmonta, ya que puede crear directorios en el punto de montaje.
uliwitness

11
directory_name = "foo"

if [ -d $directory_name ]
then
    echo "Directory already exists"
else
    mkdir $directory_name
fi

10

O si desea verificar primero la existencia:

if [[ ! -e /path/to/newdir ]]; then
            mkdir /path/to/newdir
fi

-e es la prueba de existencia para korn shell.

También puede intentar buscar en Google un manual de shell Korn.


10

mkdir ya no es compatible con -p switch en sistemas Windows 8+.

Puedes usar esto:

IF NOT EXIST dir_name MKDIR dir_name

10
OP era sobre AIX kornshell ... nada que ver con Windows, ¿verdad?
J. Chomel

9

Consultando la página del manual man mkdirpara la opción -p

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

que creará todos los directorios en una ruta determinada, si existe no arroja ningún error, de lo contrario, crea todos los directorios de izquierda a derecha en la ruta dada. Prueba el siguiente comando. los directorios newdiry anotherdirno existe antes de emitir este comando

Uso Correcto

mkdir -p /tmp/newdir/anotherdir

Después de ejecutar el comando, puede ver newdiry anotherdircrear en / tmp. Puede emitir este comando tantas veces como desee, siempre lo ha hecho exit(0). Debido a esta razón, la mayoría de las personas usan este comando en los scripts de shell antes de usar esas rutas reales.


8

Puede usar el bucle if para verificar si el directorio existe o no, si no sale, cree el directorio.

1) dir = / home / dir_name

if [ ! -d $dir ]
then
     mkdir $dir
else
     echo "Directory exists"  
fi

2) Puede usar el directorio mkdir con la opción -p para crear un directorio. Verificará si el directorio no está disponible, lo hará.

mkdir -p $dir

mkdir -p también permite crear la estructura de árbol del directorio. Si desea crear los directorios padre e hijo usando el mismo comando, puede optar por mkdir -p

mkdir -p /home/parent_dir /home/parent_dir/child1 /home/parent_dir/child2

¿Hay alguna ventaja en usar if loop? ¿Por qué alguien elegiría esa opción overp?
pedram bashiri

1
Te he compartido formas de crear las carpetas cuando no existe una carpeta. Depende del requisito de uno. Si tiene un caso de uso en el que necesita verificar si la carpeta no existe y desea hacer un seguimiento de eso para poder ir con la solución 1. Si no importa, puede ir con la solución 2, creará la carpeta si no existe
AbhinavVaidya8

No vi un bucle.
Amit Naidu

3

Esta es una función simple (bash shell) que le permite crear un directorio si no existe.

#----------------------------------
# Create a directory if it doesn't exist
#------------------------------------
createDirectory() {
    if [ ! -d $1 ]
        then
        mkdir -p $1
    fi
}

Puede llamar a la función anterior como:

createDirectory / tmp / fooDir / BarDir

Lo anterior crea fooDir y BarDir si no existen. Tenga en cuenta la opción "-p" en el comando mkdir que crea directorios de forma recursiva. Espero que esto ayude.


2
mkdir -p sam
  • mkdir = Crear directorio
  • -p = - padres
  • (sin error si existe, haga directorios principales según sea necesario)

2
if [ !-d $dirName ];then
     if ! mkdir $dirName; then  # Shorter version. Shell will complain if you put braces here though
     echo "Can't make dir: $dirName"
     fi
fi
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.