Best practice per continuare mv


13

Ho usato il terminale per copiare i file da un'unità a un'altra.

sudo mv -vi /location/to/drive1/ /location/to/drive2/

Tuttavia, ciò si interruppe improvvisamente, dopo alcune ore e senza errori, dopo aver creato una directory.

La mia soluzione a questo è spesso un mix di hashing e confronto che è per lo più un disastro che richiede tempo in quanto ora devo recuperare da una copia intermedia senza sapere davvero quali file mancano (scritto come one-liner molto lungo per zsh - nota che questo script non funziona in bash come scritto):

source_directory="/path/to/source_directory/";
target_directory="/path/to/target_directory/";
while read hash_and_file; do {
    echo "${hash_and_file}" | read hash file;
    echo "${file}" | sed "s/^/${source_directory}/g" | read copy_from;
    echo "${copy_from}" | sed "s/${source_directory}/${target_directory}/g" | read copy_to;
    mv -v "${copy_from}" "${copy_to}" | tee -a log;
    rm -v "${copy_from}" | tee -a log; };
done <<<$(
    comm -23 <( find ${source_directory} -type f -exec sha256sum "{}" \; |
                sed "s: ${source_directory}: :g" | sort;
           ) <( find ${target_directory} -type f -exec sha256sum "{}" \; |
                sed "s: ${target_directory}: :g" | sort; ) )

Questo è soggetto a errori se la directory di destinazione del nome o la directory source_directory fanno parte del percorso ed eliminano i file se non sono stati spostati perché sono stati contrassegnati come duplicati. Inoltre, non alla fine directory di origine.

Esiste una best practice su come recuperare da mv interrotta?


Ho scritto una sceneggiatura simile , che utilizza cmpinvece di hashing. Ha dipendenze e gli stessi problemi while readmenzionati da Gilles. È anche lento e dettagliato. Ma libera spazio su disco prima del metodo rsync, poiché i file vengono (ri) spostati dall'origine durante l'esecuzione. Può servire come ispirazione per i coraggiosi.
joeytwiddle,

3
@joeytwiddle offerte rsync --delete-during receiver deletes during the transfere anche diverse altre alternative utili: --delete --delete-before --delete-delay --delete-after --delete-excluded. Quindi, sì, rsync è la migliore alternativa,
Isaac

Mi manca qualcosa. Perché la ripetizione dello stesso mvcomando non funziona? Forse con l' *aggiunta al percorso sorgente se l'origine originale era una directory.
jpa,

@isaac No, temo che rsync --delete*sarebbe un disastro ! Rimuoverà le cose da destcui non sono attualmente presenti src, quindi tutti i file che sono stati spostati con successo nel tentativo precedente verranno ora eliminati! Probabilmente stavi pensando a rsync --remove-source-filesquale concordo sarebbe una buona alternativa. ( altro1 , altro2 )
joeytwiddle il

@joeytwiddle No, rsync --deletesarà solo rimuovere gli altri file che non fanno parte della fonte. Da [man rsync] () * elimina i file estranei dalle directory dir *. Comprendi cosa significa estraneo : non essere sincronizzato. E sì, rsync fornisce anche un modo per rimuovere i file sorgente dopo che sono stati correttamente trasmessi.
Isaac,

Risposte:


46

Dimentica di provare a reinventare rsync e usa rsync.

sudo rsync -av /location/to/drive1/ /location/to/drive2/

Assicurati di utilizzare una barra finale sull'origine, altrimenti verrebbe copiato /location/to/drive2/drive1.

Ricontrolla che il comando sia riuscito, quindi esegui rm -rf /location/to/drive1/.

Il comando sopra sovrascriverà qualsiasi file preesistente da drive2. Se si desidera richiedere all'utente di saltare i file già esistenti in drive2, come con mv -i, è più complicato, perché ora è necessario distinguere i file che sono già stati copiati e quelli che non lo sono. È possibile passare l' --ignore-existingopzione a rsync per saltare i file già esistenti sulla destinazione indipendentemente dal loro contenuto. Si noti che se l'originale è mvstato interrotto durante la creazione di un file, questo file rimarrà nel suo stato semi-copiato (mentre un nudo rsync -afinirebbe correttamente di copiarlo).

Se si desidera riprodurre il comportamento esatto di mv -i, incluso il prompt, potrebbe essere fatto, ma è molto più complicato.

Nota che la tua fodera da un gigante è molto fragile. Se ci sono nomi di file contenenti barre rovesciate o newline, potrebbero non essere copiati correttamente o potrebbero persino ingannare il tuo script per rimuovere file arbitrari. Quindi non utilizzare il codice nella domanda a meno che tu non sia sicuro di poterti fidare dei nomi dei file per non contenere barre rovesciate o nuove righe.

Per riferimento futuro, raccomando di non usare mai mvper grandi spostamenti cross-drive, proprio perché è difficile controllare cosa succede se viene interrotto. Utilizzare rsync per eseguire la copia, quindi rimuovere l'originale.


Quali promesse fa rsync che mv non lo fa?
Che

4
bene, per esempio rsyncfa quello che stai cercando di fare, mentre mvnon lo fa. Inoltre: copia tra macchine diverse; compressione per trasferimento; saltare i file esistenti nella destinazione in base all'uguaglianza basata su data o ora; gestione configurabile della proprietà, autorizzazioni, collegamenti e file speciali; ecc. linux.die.net/man/1/rsync
Silly Freak

1
@SillyFreak dovrei concludere da ciò, che dovrei sempre usare rsync invece di mv, non solo come diceva Gilles per cross-drive, ma qualsiasi operazione, in quanto il limite di "troppo grande" è relativamente soggettivo e se si tratta di un problema sarebbe stato risolto da rsync comunque?
Che

9
bene, quando sposto file o directory all'interno di una partizione, di solito uso mv(o il file manager) perché sposta solo un riferimento al file / directory. Se devo effettuare il trasferimento di dati effettivo, lo uso rsyncse è vera una delle seguenti condizioni: 1) Sto spostando più file di quanti ne riesca a controllare a colpo d'occhio; 2) Prevedo che dovrò sincronizzare i file; 3) Mi aspetto che il trasferimento potrebbe essere interrotto. Il mio punto è, per il caso d'uso che stai presentando nella domanda, rsyncè semplicemente lo strumento giusto, mvo cpno.
Silly Freak,

7
Consiglio di eseguire sempre qualsiasi comando rsync con -v e —dry-run prima per confermare esattamente cosa sta per fare.
Darren,
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.