Ho appena "mv" modificato una directory da 49 GB in un percorso di file errato, è possibile ripristinare lo stato originale dei file?


58

Ho (beh, ho avuto ) una directory:

/media/admin/my_data

Aveva una dimensione di circa 49 GB e conteneva decine di migliaia di file. La directory è il punto di montaggio di una partizione LUKS attiva.

Volevo rinominare la directory in:

/media/admin/my_data_on_60GB_partition

Non mi ero reso conto in quel momento, ma ho emesso il comando dalla directory home quindi ho finito per fare:

~% sudo mv /media/admin/my_data my_data_on_60GB_partition

Quindi il mvprogramma ha iniziato a spostarsi /media/admin/my_datae il suo contenuto in una nuova directory ~/my_data_on_60GB_partition.

Ho usato Ctrl+ Cper annullare il comando a metà, quindi ora ho un sacco di file suddivisi in directory:

~/my_data_on_60GB_partition    <---  about 2GB worth files in here

e

/media/admin/my_data           <---- about 47GB of orig files in here    

La nuova directory ~/my_data_on_60GB_partitione alcune delle sue sottodirectory sono di proprietà di root.
Suppongo che il mvprogramma abbia inizialmente copiato i file come root e poi dopo il trasferimento chownli abbia riportati nel mio account utente.

Ho un backup un po 'vecchio della directory / partizione.
La mia domanda è: è possibile ripristinare in modo affidabile il gruppo di file che sono stati spostati?

Cioè, posso semplicemente eseguire:

sudo mv ~/my_data_on_60GB_partition/*  /media/admin/my_data

o dovrei rinunciare a tentare di recuperare, poiché i file sono corrotti e parzialmente completi, ecc.?

  • Sistema operativo - Ubuntu 16.04
mv --version  
mv (GNU coreutils) 8.25

36
Prendi l'abitudine quando vai nel panico di digitare Control-Z(per mettere in pausa) piuttosto che Control-C. In questo caso, sarai quindi in grado di vedere quale file è stato trasferito in quel momento e quindi sapere quale file è stato copiato solo parzialmente. Puoi quindi decidere con calma su come procedere. (Utilizzare kill -stopper processi non inclusi in tty).
Meuh

1
2 GB + 47 GB = 60 GB ???
martedì

7
@tbodt (2GB + 47GB) < 60GB. la capacità della partizione è di 60 GB, la dimensione della cartella e il suo contenuto: 49 GB.
the_velour_fog

Risposte:


87

Quando si spostano file tra filesystem, mvnon elimina un file prima che abbia finito di copiarlo, ed elabora i file in sequenza (inizialmente ho detto che copia e poi cancella ogni file a sua volta, ma ciò non è garantito - almeno le mvcopie GNU quindi elimina ogni comando- riga argomento a sua volta e POSIX specifica questo comportamento ). Quindi dovresti avere al massimo un file incompleto nella directory di destinazione e l'originale sarà ancora nella directory di origine.

Per spostare indietro le cose, aggiungi la -ibandiera in modo da mvnon sovrascrivere nulla:

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

(supponendo che non ci siano file nascosti da cui ripristinare ~/my_data_on_60GB_partition/), o meglio ancora (dato che, come hai scoperto, potresti avere molti file in attesa di essere eliminati), aggiungi il -nflag in modo da mvnon sovrascrivere nulla ma non chiedertelo:

sudo mv -n ~/my_data_on_60GB_partition/* /media/admin/my_data/

Puoi anche aggiungere la -vbandiera per vedere cosa si sta facendo.

Con qualsiasi conforme POSIX mv, la struttura di directory originale dovrebbe essere ancora intatta, quindi in alternativa è possibile verificare che - ed eliminare semplicemente /media/admin/my_data... (Nel caso generale, penso che la mv -nvariante sia l'approccio sicuro - gestisce tutte le forme di mv, incluso ad es mv /media/admin/my_data/* my_data_on_60GB_partition/ .)

Probabilmente dovrai ripristinare alcune autorizzazioni; puoi farlo in massa usando chowne chmod, o ripristinandoli da backup usando getfacle setfacl(grazie a Sato Katsura per il promemoria ).


Grazie Stephen Kitt, è di grande aiuto! Posso usare findper trovare e impostare le autorizzazioni. Ci sono molti file nella nuova directory che hanno spazi nei nomi dei file, ma nessun file nascosto - di cui sono a conoscenza. Pensi che il glob nel comando sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/amplierebbe il nome del file senza problemi di divisione delle parole? Stavo pensando in alternativa che potrei usare sudo rsync ~/my_data_on_60GB_partition/ /media/admin/my_data/quale credo che gestisca i percorsi dei file con spazi?
the_velour_fog

6
Giusto per essere sicuro, quando accadono cose come OP descritte, uso rsyncinvece, quindi verificherebbe anche l'integrità di tutti i file. Ma è bello sapere che non ne ho bisogno.
Hauleth,

1
@the_velour_fog globbing gestisce senza problemi gli spazi nei nomi dei file.
Stephen Kitt,

5
Avrei su command mv -i ...(o su /bin/mv -i ...), invece di sudo mv -i ...), nel caso in cui qualche (strano) amministratore rendesse "mv" una funzione che fa "mv -f" a livello di sistema (cioè, / etc / profile o file di questo tipo). comando qualcosa: avvia il comando qualcosa e non una funzione o un alias con lo stesso nome. (per esempio: uno potrebbe essere (molto!) sfortunato e avere un (molto, molto cattivo!) function mv { /bin/mv -f -- "$@" }in un file che è sempre di provenienza, e quindi "rm -i qualcosa" non chiederà nulla (e semplicemente protesterà "-i "il file non esiste!) ... [Ho visto cose del genere ... brividi ]
Olivier Dulac,

3
@OlivierDulac - un perfetto esempio del perché è una cattiva pratica usare alias o script con gli stessi nomi dei programmi standard.
Joe,

19

Dopo aver ottenuto la risposta di Stephen Kitt e aver discusso questo comando come una potenziale soluzione:

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

Ho deciso di smettere di gestirlo fino a quando non ho avuto la testa su ciò che stava accadendo, questa risposta descrive ciò che ho scoperto e ho finito per fare.

Sto usando Gnu mvche copia i file sulla destinazione, quindi solo se l'operazione di copia ha esito positivo, elimina l'originale.
Tuttavia, volevo confermare se mvesegue questa sequenza un file alla volta, se ciò fosse vero, il contenuto della cartella originale sarebbe stato suddiviso in due parti, una parte spostata a destinazione, l'altra ancora lasciata alla fonte. E forse ci sarebbe stato un file che era stato interrotto durante la copia che sarebbe comune tra le due directory - e sarebbe probabilmente malformato.

Per scoprire i file comuni tra le due directory, ho eseguito:

~% sudo diff -r --report-identical-files my_data_on_60GB_partition/. /media/admin/mydata/. | grep identical | wc -l
14237

Questo risultato ha suggerito che c'erano 14.237 istanze degli stessi file in entrambe le directory di origine e di destinazione, ho confermato controllando i file manualmente - sì, c'erano molti degli stessi file in entrambe le directory. Ciò suggerisce che solo dopo mvcopie grandi quantità di file esegue l'eliminazione dei file di origine. Una rapida occhiata infoal mvcomando mostrò

Per mvprima cosa usa parte dello stesso codice utilizzato cp -aper copiare le directory e i file richiesti, quindi (supponendo che la copia sia riuscita) rimuove gli originali. Se la copia non riesce, la parte che è stata copiata nella partizione di destinazione viene rimossa.

Non ho eseguito il comando ma sospetto che se avessi provato a eseguire

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

Il -i prompt prima della sovrascrittura probabilmente si sarebbe attivato più di 14.000 volte.

Quindi, per scoprire quanti file totali nella directory appena creata:

~% sudo find my_data_on_60GB_partition/ -type f -a -print | wc -l                                                                    
14238

Quindi, se c'erano un totale di 14238 file regolari nella nuova directory e 14237 avevano originali identici nella sorgente, ciò significa che c'era un solo file nella nuova directory che non aveva un file identico corrispondente nella sorgente. Per scoprire quale fosse quel file, ho eseguito rsync indietro nella direzione del sorgente:

~% sudo rsync -av --dry-run my_data_on_60GB_partition/ /media/admin/my_data
sending incremental file list
./
Education_learning_reference/
Education_learning_reference/Business_Education/
Education_learning_reference/Business_Education/Business_education_media_files/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/018 business plans-identifying main KPIs.flv

sent 494,548 bytes  received 1,881 bytes  330,952.67 bytes/sec
total size is 1,900,548,824  speedup is 3,828.44 (DRY RUN)

Un rapido controllo ha confermato che si trattava del file non valido, in cui il file esisteva sia sull'origine che sulla destinazione, file di destinazione = 64 MB, originale = 100 MB. Questo file e la sua gerarchia di directory erano ancora di proprietà di root e non avevano ancora ripristinato le autorizzazioni originali.

Quindi in sintesi:

  • tutti i file che mvnon sono mai stati raggiunti sono ancora nella loro posizione originale (ovviamente)
  • tutti i file che mvhanno copiato completamente avevano ancora le loro copie originali nella directory di origine
  • il file che era stato copiato solo parzialmente aveva ancora l'originale nella directory di origine

In altre parole, tutti i file originali erano ancora intatti e la soluzione in questo caso era semplicemente eliminare la nuova directory!


Wow ... ho aggiornato la mia risposta, -nsarebbe meglio nel caso generale. Ho controllato il mvcodice sorgente, elimina l'origine un argomento alla volta.
Stephen Kitt,

@StephenKitt ah nice. Mi chiedevo quando mvfa la cancellazione sulla fonte. Quindi il comando mv foo bar bazsi sposterebbe fooper baz/foo poi cancellare l'originale e foopoi barsu baz/bar..?
the_velour_fog

Sì, è giusto; in effetti questo è ciò che POSIX specifica (sostanzialmente, in modo che qualsiasi errore che influisca su qualsiasi argomento sorgente lasci intatta l'intera gerarchia dei sorgenti).
Stephen Kitt,

Penso che avresti potuto usare diff per trovare anche l'unico file incompiuto.
StarWeaver,

1
Dovresti usare cmpinvece di diffconfrontare i file binari. Inoltre, la discussione di cui sopra ha senso solo quando si spostano file su diversi file system. Non è richiesta la copia quando si spostano file all'interno dello stesso filesystem.
Satō Katsura,

4

Ho solo pensato di commentare che alcune persone potrebbero essere tentate di lanciare "xargs" nel mix per far funzionare le cose in parallelo. Questo mi dà i willies e mi piace molto la soluzione rsync sopra.

Per quanto riguarda le cose del filesystem sullo spostamento e sulla copia e quando esattamente l'originale viene eliminato, il VFS e il / i filesystem / i sottostante / i si coordinano per garantire atomicità per file prima di arrivare a quel passaggio di eliminazione. Quindi, anche se viene interrotto prima che il file di destinazione sia completamente scritto, tutto il blocco in VFS è molto rigoroso e protegge da cose come l'interleaving di dati casuali anche in casi paralleli. (Ho lavorato su cose Linux VFS e NFS4)

L'aggiunta di "xargs" al mix avrebbe probabilmente reso la fase di verifica del doppio controllo un mal di testa, con più file in transito. Vorrei avere più scripting a livello di sistema. Buoni promemoria per me!

Mi è piaciuta la domanda, buona per le ragnatele, e mi fa amare di nuovo rsync. Saluti!


1
Per non parlare del problema quando i nomi dei file contengono spazi bianchi.
Wildcard il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.