Spostare i file ed eliminare le directory con rsync?


17

Recentemente ho dovuto eliminare un gran numero di file (oltre 1 milione) e ho letto che facendo:

rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

È stato uno dei modi più ottimizzati per farlo e posso garantire che è più veloce di rm -rf.

Non sono un esperto in materia, ma dalla mia comprensione il motivo delle prestazioni di rsync ha qualcosa da fare nel modo in cui elenca i file (LIFO invece di FIFO suppongo). Ora, il problema è che devo anche spostare un gran numero di file in modo efficiente. Dopo aver cercato un po ', ho trovato questo:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination

Anche se questo elimina tutti i spostati file in ~/source, le directory ci rimangono. Dato che ho una struttura di directory simile a "round robin", il numero di files/directoriesè molto vicino a 1, quindi sono costretto a eseguire nuovamente il primo comando per eliminare completamente la directory:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination && \
rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

Una scala mvfinirebbe praticamente all'istante, ma la mia ~/destinationdirectory ha dei file che dovrebbero essere mantenuti, quindi mvnon è un'opzione. Ho trovato le opzioni --prune-empty-dirse --forcersync, ma nessuna delle due sembra funzionare come mi aspetterei:

--force                 force deletion of directories even if not empty
--prune-empty-dirs      prune empty directory chains from the file-list
--remove-source-files   sender removes synchronized files (non-dirs)

C'è un modo per imitare una mossa con rsync in una volta sola?


2
Se non trovi una risposta qui, prova a postare nell'elenco rsync. Sono molto utili. lists.samba.org/mailman/listinfo/rsync
Joe

Risposte:


7

Ho trovato questo thread su StackOverflow intitolato: Eliminare le cartelle con rsync "move"? , che pone essenzialmente la stessa domanda. Una delle risposte ha suggerito di eseguire i rsynccomandi in 2 poiché sembra che non vi sia un singolo comando in grado di eseguire lo spostamento / rimozione dei file e delle directory di origine.

$ rsync -av --ignore-existing --remove-source-files source/ destination/ && \
  rsync -av --delete `mktemp -d`/ source/ && rmdir source/

In alternativa puoi farlo usando questo comando:

$ rsync -axvvES --remove-source-files source_directory /destination/ && \
  rm -rf source_directory

Non ideale ma fa il lavoro.


Sì, sono stato io a rispondere a quella domanda (e la stessa "soluzione" è anche su questa domanda). = P
Alix Axel,

@AlixAxel - Ah, scusa se non mi sono nemmeno accorto che hai risposto a quello. Oh bene. Devo cancellare questa risposta allora?
slm

3
Usare rsyncper potare le directory non è giusto e c'è sempre pericolo rm -rf. Consiglierei che il secondo passo sia:find source/ -d -type d -exec rmdir {} \;
1313

2
Mi sento solo costretto ad aggiungere, non usare mai -deletee --remove-source-filesin un singolo comando rsync (gli esempi precedenti vanno bene, questo è tangenziale). Se interrompi e riesegui ciò che sto descrivendo, perderai i file trasferiti. Cosa che ho fatto prima :(
Sridhar Sarnobat,

Quando pulisco find, preferisco questo: find source/ -type d -empty -delete mi dà uno strano senso di rassicurazione che non si limiterà a ostruire tutto.
greyfade,

10

Dal commento di zany alla risposta di slm ( spostare i file ed eliminare le directory con rsync? ) Consiglierei questi 2 comandi come risposta:

rsync -av --ignore-existing --remove-source-files source/ destination/ && \
find source/ -depth -type d  -empty -exec rmdir "{}" \;

Il vantaggio è, come ha detto zany, che c'è ancora qualche pericolo nell'uso di rm -rf se non lo capisci bene o per i principianti.

Ho aggiunto 2 opzioni, -depth e -empty e anche se non sono sicuro che ciò sia davvero necessario, rende il 2 ° comando più portatile per altre situazioni e ancora più sicuro (fa ancora la cosa giusta se alcune directory non sono vuote e inizia a rimuovere dal punto più profondo in un albero di directory)


perché non solo -deleteinvece di -exec rmdir {} \;?
volo di pecore il

@flying_sheep vedi il commento di user7000 nella risposta del sim: quando rsync viene interrotto potresti perdere file
mit

Quando rsync viene interrotto, la ricerca non inizia mai o no? Quindi la cancellazione in un secondo rsync non dovrebbe essere un problema. Ma -delete rimuove anche i file, invece rmdir non elimina mai i file, solo le directory. Entrambi (-delete e rmdir) controllano le directory se sono vuote prima dell'eliminazione.
benba,

Inoltre le pagine man dicono che dovresti usare -execdir invece di -exec ...
benba,

2

Questo fa il lavoro in un solo passaggio. Nota il trailing / slash / su entrambi i percorsi di origine e destinazione.

rsync \
    -ruval \
    --ignore-existing \
    --remove-source-files \
    --prune-empty-dirs \ 
    /source/path/ /target/path/

Mi associo alla cautela di user7000 di non utilizzare --deletee --remove-source-filesinsieme nella stessa chiamata a rsync. Se l'operazione fallisce o viene interrotta e la stessa chiamata viene ripetuta, si perderanno i dati. In caso di dubbio, utilizzare l' --dry-runopzione per vedere cosa sarebbe stato fatto.


-ruvalsembra ridondante. -aè equivalente a -rlptgoD, che include sia -re -l.
Greyfade,
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.