¿Sobrescribir un directorio existente?

11

Tengo un nombre de directorio fooubicado en ~/Desktop. Supongamos que quiero crear un directorio desde una terminal con el mismo nombre y en la misma ubicación. Cuando lo intenté mkdirme dio un error:

mkdir: cannot create directory `/home/nux/Desktop/foo': File exists

Eso tiene sentido, pero quiero reemplazar foosi existe. Miré a través man mkdirpero no hay ninguna opción que haga eso.

Entonces, ¿cómo sobrescribir el foodirectorio?

¿Por qué no mkdirtiene una opción para hacer esto?

nux
fuente
Reemplazar foocomo en eliminar todo el contenido de la misma? mkdirtiene una -popción que ignora si el directorio existe.
muru
44
Entonces, ¿desea un comando que elimine todos los archivos en un directorio cuando crea accidentalmente un nuevo directorio con el mismo nombre? ¿Y te preguntas por qué no es una opción? ¿Esto es una broma?
Marty Fried
downvoters acaba de aclarar por qué, estoy preguntando por un comando que borrar un directorio existente
Nux
1
@nux para mí, la pregunta no tiene sentido ... explica por qué alguna vez quieres eliminar y volver a crear un directorio. Tenemos comandos para todo lo que necesite hacer al directorio. mkdir no necesita una opción para eliminar / recrear.
Rinzwind
1
¿Es un crimen aquí si estoy haciendo una pregunta lógica?
nux

Respuestas:

21

Si su objetivo es ejecutar un comando de una línea que:

  • Elimina y ~/Desktop/foovuelve a crear el directorio si ya existe.
  • Simplemente crea el directorio ~/Desktop/foosi aún no existe.

Entonces puedes usar:

rm -r ~/Desktop/foo; mkdir ~/Desktop/foo

; es equivalente a una nueva línea, pero le permite ejecutar múltiples comandos en una sola línea (es decir, como un "comando único").

  • Si el directorio que está eliminando puede contener archivos de solo lectura, necesitará el -findicador para eliminarlos sin solicitar al usuario de forma interactiva. Esto está bien, pero recomiendo ser especialmente cuidadoso rm -rf .... Ver man rmpara más detalles.
  • Necesita que el rmcomando termine antes de que se mkdirejecute el comando; esta es la razón para usar en ;lugar de &. (Un comando anterior se &ejecuta de forma asíncrona en segundo plano).
  • Necesita que el mkdircomando se ejecute cuando el rmcomando tenga éxito; esta es la razón para usar en ;lugar de ||.
  • Necesita que el mkdircomando se ejecute cuando el rmcomando falla (por lo general, el error significará que el directorio ya no existía); esta es la razón para usar en ;lugar de &&.
  • El rmcomando puede fallar incluso cuando el directorio ya existía, en cuyo caso el mkdircomando también fallará, pero los mensajes de error tendrán sentido y probablemente no sea necesario agregar un paso intermedio para verificar foola existencia antes de intentar crearlo.

Ver 3.2.3 listas de comandos en el Manual de Referencia de Bash para obtener más información y una explicación acerca de los ;, &, ||, y &&los operadores.

Como muru sugirió (y Rinzwind explicó ), le recomiendo que investiguersync para ver si cumple con sus necesidades de respaldo. Hay algunas guías útiles adicionales en la página de documentación de rsync , así como esta guía de Ubuntu rsync .

¿Por qué mkdir no tiene esta opción?

mkdircrea directorios (el "mk" significa "make" ). Que también elimine recursivamente directorios y todos los archivos en ellos sería malo, ya que violaría el principio de menor asombro de una manera que probablemente conduciría a la pérdida de datos.

rmdirni siquiera elimina los directorios que tienen archivos (que no sean directorios). rmtiene una -ropción, lo cual tiene sentido ya que rmse espera que elimine los archivos (ese es su propósito, por lo tanto, el peligro inherente es intuitivo y los usuarios generalmente deben tener cuidado al ejecutar rmcomandos).

Eliah Kagan
fuente
+1 excelente. Esta respuesta va más allá al explicar la sintaxis, algo que desearía que fuera más profundo en los sitios de intercambio de pila. Hay muchas pepitas de oro en esta respuesta.
Govind Rai el
7

No, no hay un solo comando para hacer lo que está pidiendo.

¿Por qué?

Esta es la filosofía de Unix: escribir programas que hagan una cosa y que lo hagan bien. Escribir programas para trabajar juntos. 1

En este caso, los comandos mkdiry rmhacen lo que necesita y funcionan bien juntos, ya que rm -rtambién eliminarán el directorio, por lo que un subsiguiente mkdircreará el directorio.

1 The Art of Unix Programming , Eric S. Raymond, citando a Doug McIlroy.

muru
fuente
por ahora, esa es una buena respuesta,
buscaré
3

El comando para eliminar un directorio es rm. Entonces necesitas 2 comandos.

rm -r ~/Desktop/foo/
mkdir ~/Desktop/foo/

Como se muestra en los comentarios, puede encadenarlos con ;(= hacer ambas cosas incluso si la primera falla) o &&(= solo mkdir cuando la rm no falla).

El -res para eliminar directorios. El primer comando también elimina TODOS los contenidos del directorio. Si esa NO es su intención, tanto rm como mkdir no son lo que está buscando: los permisos son chmody chown.

¿Por qué mkdir no tiene esta opción?

Ambigüedad. mkdirsignifica hacer directorio. No eliminar y hacer directorio. Y dado que el rmcomando es para eliminar cosas, no hay necesidad de rmdirpoder eliminar un directorio.

Rinzwind
fuente
Lo sé, pero quiero decir un comando, puedes ver mi edición. Lo cambio
Nux
Primero, explique por qué necesita volver a crear el directorio. Eso no tiene sentido.
Rinzwind
¿Tiene sentido mi necesidad? Me pregunto cómo. tiene sentido para mí :)
nux
@nux no, no lo hace. Y tampoco el mantenedor de mkdir entiende por qué;) Lo que quieres es inútil y no tiene mérito.
Rinzwind
ok si quieres saber que estoy haciendo un script para hacer una copia de seguridad en un nuevo directorio con el mismo nombre de foo y permite reemplazarlo si existe para reducir espacio
nux
1

Para hacer eso de la manera más limpia, uso esto:

create_clean_directory(){
    dir_name=$1
    if [ -d "$dir_name" ]; then
        echo "Removing $dir_name"
        rm -rf "$dir_name"
    elif [ -f "$dir_name" ]; then
        echo "File with this name already exists, not a directory."
        exit
    fi
    if mkdir "$dir_name"; then
        echo "Clean directory created: $dir_name"
        return 0
    else
        echo "Creating directory failed: $dir_name"
        return 1
    fi 
}

Y para usarlo:

create_clean_directory <dir_name>

Esto asegura que lo que está intentando eliminar es un directorio y no un archivo:

  1. -dCompruebe si ya existe un directorio con ese nombre. Si es así, bórrelo.

  2. -fVerifique que no exista ningún archivo con este nombre. Si es así, imprima el mensaje de error y salga.

  3. Cree el nuevo directorio y echo con éxito, o si falla, echo falla.

Rea Haas
fuente