¿Qué sucede si se interrumpe mv?

72

¿Qué sucede si mvse interrumpe el comando de Linux ? Digamos, estoy moviendo un directorio completo a otro lugar y lo interrumpo mientras se mueve. ¿El directorio fuente seguirá intacto?

Dehmann
fuente

Respuestas:

51

Si mueve un directorio en el mismo sistema de archivos, solo mueve la entrada del directorio de una ubicación en el sistema de archivos a otra. Por ejemplo, mv /source/dir /target/direliminará la entrada de directorio de dirfrom /sourcey creará una nueva en /target. Eso se hace mediante una llamada al sistema atómico (es decir, ininterrumpible). El inodo que contiene las entradas del directorio diry el contenido real del directorio en sí no se ve afectado.

Si mueve el directorio de un sistema de archivos a otro, todos los archivos se copian primero al nuevo sistema de archivos y luego se desvinculan del original. Entonces, si interrumpe mvmientras se está copiando, puede terminar con dos copias de algunos de los archivos, en la ubicación anterior y en la nueva.

bmk
fuente
66
@ Wesley: No, no habrá un archivo parcial. Si el sistema se mantiene activo (por ejemplo, si presiona Ctrl-C), se eliminará automáticamente. Si no es así (p. Ej., Pérdida de energía), el archivo parcial puede dejarse en algún lugar inaccesible en el disco de destino, pero debe ser limpiado por el siguiente fsck(que probablemente se ejecutará automáticamente al reiniciar, ya que el disco no se desmontó limpiamente).
Dave Sherohman
50
Incorrecto. Si mueve dir de una fs a otra mv / fs1 / dir / fs2 / e interrumpe, / fs1 / dir / permanecerá aquí por completo. / fs1 / dir se elimina solo cuando se completa el movimiento.
8
user263131 tiene razón. Ejecutar strace mv /fs1/dir /fs2/: lo último que hace mv es invocar unlinkattodos los archivos de origen a la vez (no uno por uno a medida que se copian).
Jakob
77
@JJ Parece que es porque usaste una expansión bash, en cuyo caso mv trata cada archivo en la expansión como una fuente separada (haciéndolos individualmente).
gkanwar
55
Entonces ... @bmk u otros, ¿quieres actualizar esta respuesta para que sea menos ... incorrecta?
Artem Russakovskii
35

La implementación de GNU itera sobre los argumentos en la línea de comando, intenta cambiar el nombre primero y, si eso falla, copia recursivamente y luego borra recursivamente la fuente. Entonces

mv a b c/

eliminará a antes de copiar b , y no comenzará a eliminar nada en a antes de que se complete la copia de destino.

Tenga en cuenta que esto solo se aplica a la implementación de GNU.

Para aclarar: si una es un directorio que contiene D y E , y B es un archivo, el orden será

  • crear c / a
  • copiar a / d -> c / a / d
  • copia a / e -> c / a / e
  • eliminar a / d
  • eliminar a / e
  • eliminar un
  • copia b -> c / b
  • eliminar b
Simon Richter
fuente
1
¿Puedes proporcionar una fuente para esto? Otros respondedores dicen que un archivo fuente se elimina inmediatamente después de que se copia a una fs diferente (es decir, no todos se copian y luego se eliminan todos).
jamesbtate
1
Experiencia. Agregué un ejemplo para aclarar cómo mi respuesta y las demás son consistentes. Si solo enumera archivos individuales, cada archivo se eliminará de inmediato.
Simon Richter
Observo el comportamiento descrito en esta respuesta en macOS, es decir, también con un BSD mv, por lo que no es solo GNU.
kirelagin
12

Mueve un directorio, interrumpe el movimiento y el directorio original permanecerá intacto:

$ mv a b/

Si mueve varios directorios, cada uno estará intacto en el origen o en el destino, dependiendo de cuándo interrumpió:

$ mv a b c/

Cómo obtuve mi respuesta:

$ mv --version
mv (GNU coreutils) 8.21

$ info mv
... It first uses some of the same code that's used by `cp -a'
to copy the requested directories and files, then (assuming the copy
succeeded) it removes the originals.  If the copy fails, then the part
that was copied to the destination partition is removed.  If you were
to copy three directories from one partition to another and the copy of
the first directory succeeded, but the second didn't, the first would
be left on the destination partition and the second and third would be
left on the original partition.

Como prueba, copié una carpeta grande en un directorio NFS, la interrumpí y el número de archivos en mi carpeta grande fuente permaneció igual, y el contenido parcial se dejó en el directorio NFS. Usé "find. -Type f | wc -l" para verificar.

Parece que la respuesta de Simon es correcta.

user79878
fuente
9

La respuesta aceptada es definitivamente errónea sobre moverse entre sistemas de archivos, un hecho que ya me ahorró muchos problemas un par de veces. Al mover un directorio que contiene subdirectorios, no se eliminará ningún archivo en un subdirectorio antes de que se haya copiado todo el subdirectorio. Esto es, por cierto, el significado real de "objeto por objeto": un subdirectorio ES un objeto (archivo) y, por lo tanto, su integridad debe ser preservada por una copia completa en el destino antes de que se pueda eliminar algo. Entonces la respuesta de Simon me parece la correcta.

bhak
fuente
4

No. mv opera objeto por objeto, por lo que los objetos que ya han sido procesados ​​se eliminarán de la fuente.

Ignacio Vazquez-Abrams
fuente
2

Definitivamente no. El movimiento se realiza objeto por objeto. Por lo tanto, el objeto movido al destino hasta el punto de interrupción ya no existirá en la fuente.

Si se emitió mv para un archivo grande (entre diferentes) y se ha interrumpido, la fuente estará intacta. En el objetivo verá un archivo incompleto hasta el punto de interrupción.

Sin embargo, puede restaurar el mv con el mismo comando y el proceso continuará.

g24l
fuente
2

Si desea interrumpir mv porque desea desconectarse del terminal, puede enviarlo a un segundo plano:

* press Ctrl+Z

# bg
# disown
Курочка Ряба
fuente
1
Ese es un buen punto, pero no responde la pregunta real.
Julie Pelletier
1
@JuliePelletier, pero eso es lo que estaba buscando para que alguien pueda estar interesado en hacer esto.
Курочка Ряба