Come posso usare rsync per duplicare un albero di directory, creando collegamenti a file?


23

Di tanto in tanto, devo eseguire diverse grandi modifiche alla migrazione sui file di dati sul mio server e sto cercando un buon modo per farlo. Stavo pensando di utilizzare rsync per duplicare la mia struttura di directory partendo dalla cartella dei dati di root, creando collegamenti reali a tutti i file originali (alcuni di essi sono piuttosto grandi) e posso sovrascrivere nella struttura di destinazione solo i file che devono essere migrati. Alla fine, posso tranquillamente passare dai vecchi file ai nuovi file con due mvoperazioni.

Tuttavia, non riesco a convincere rsync a farlo. Provai

rsync -a --link-dest=$DATA $DATA $DATA/../upgrade_tmp

ma invece di creare collegamenti reali ai file, rsync li copia interamente. Si è verificato un problema durante l'utilizzo della stessa directory sorgente e collegamento-dest?

Risposte:


21

rsync è uno strumento potente, ma sfortunatamente è stranamente esigente per alcuni dei suoi nomi di percorso.

Se $DATAè un percorso assoluto (ovvero inizia con a /), la riga di comando corretta da utilizzare è:

rsync -a --link-dest=$DATA $DATA/ $DATA/../upgrade_tmp

[Ora, solo un breve accenno alla rsyncstranezza. Nota il trailing /aggiunto all'argomento source. Questo dice rsyncdi lavorare con i contenuti della directory di origine, piuttosto che con la directory di origine stessa. (Suppongo che $DATAnon contenga già un trailing /.) In questo caso, vogliamo lavorare con i contenuti, quindi aggiungiamo il trailing /.]

Se, d'altra parte, $DATAè un percorso relativo (cioè non inizia con a /), allora il commento di Sean R su --link-destè bang on: Il percorso dest-link viene interpretato in relazione al percorso di destinazione , quindi useresti quanto segue:

rsync -a --link-dest=../`basename $DATA` $DATA/ $DATA/../upgrade_tmp

MODIFICARE

Un'ultima nota, si scopre che la seconda rsyncriga di comando che ho dato dovrebbe funzionare indipendentemente dal fatto che $DATAsia un percorso assoluto, poiché basenamenon importa se un percorso è assoluto o relativo.


1
Solo una barra mancante, che ci avrebbe pensato ... Grazie per la bella spiegazione!
Jean-Philippe Pellet,

Grazie per questo, ho provato a seguire diverse istruzioni di backup incrementali, come questa e non ho trovato alcuna menzione di questa stranezza. Questa è stata l'unica cosa che ha effettivamente assicurato che i file fossero linkati. Controllando che il conteggio di ref fosse> 1 e che i numeri di inode fossero gli stessi conls -ilah
Walf

L'ho usato insieme alla funzione relpath () descritta in unix.stackexchange.com/a/85068/57414 per eseguire il backup di una $SOURCEdirectory in una directory $TARGETcome questa:SOURCE='abs_path_to_backup'; TARGET='.'; rsync -a --link-dest=$(relpath $TARGET $SOURCE) $SOURCE/ $TARGET/
Nathan S. Watson-Haigh

13

Quello che vuoi è "cp -al":

cp -al $DATA/ $DATA/../upgrade_tmp/
  • -a reclute come rsync -a
  • -l collegherà i file invece di copiarli.

1
cp -alpurtroppo non è disponibile sul mio sistema (Mac OS X 10.6). Userò invece pax ...
Jean-Philippe Pellet,

7

L' --link-destopzione in rsyncè relativa alla directory di destinazione , non alla directory corrente. Quindi quello che vuoi è:

rsync -a --link-dest=../`basename $DATA` $DATA $DATA/../upgrade_tmp

Oops, intendevo basename, originariamente avevo dirname.
Sean Reifschneider,

1
La pagina man dice che l' --link-destopzione, se relativa , è relativa alla directory di destinazione. Nel mio caso è assoluto. Anche renderlo relativo alla directory di destinazione non funziona.
Jean-Philippe Pellet,

7

Si scopre che è più difficile farlo con rsyncche con altri strumenti. La risposta corretta per rsyncè quella di Steven Monai, ma il modo più semplice per farlo è utilizzare uno cp -alo pax -rwlsu sistemi in cui -lnon è un'opzione valida per cp:

pax -rwl $DATA $DATA/../upgrade_tmp

o

cp -al $DATA/ $DATA/../upgrade_tmp/

4

Per me funziona:

$ rsync --hard-links --recursive --link-dest=/local user@host:/remote/ /local

Uso rsync versione 3.1.0.

Da uomo :

--hard-link

Indica a rsync di cercare file con collegamenti fissi nel trasferimento, senza questa opzione, i file con collegamenti fissi nel trasferimento vengono trattati come se fossero file separati.

--link-dest = DIR

I file invariati sono strettamente collegati da DIR alla directory di destinazione. I file devono essere identici in tutti gli attributi conservati (ad es. Autorizzazioni, possibilmente proprietà) affinché i file possano essere collegati insieme


2
Solo lo snippet di codice non è sufficiente, spiega cosa fa e perché.
Peter dice di reintegrare Monica il

--hard-links Indica a rsync di cercare file con collegamenti fissi nel trasferimento, senza questa opzione, i file con collegamenti fissi nel trasferimento vengono trattati come se fossero file separati. --link-dest = DIR I file invariati sono strettamente collegati da DIR alla directory di destinazione. I file devono essere identici in tutti gli attributi conservati (ad es. Permessi, possibilmente proprietà) affinché i file possano essere collegati insieme.
Alexander Fedorov,

1
Meraviglioso. Grazie. In realtà, ho trovato la tua risposta nella coda "bassa qualità". Significa che c'è stato un voto se la tua risposta dovesse essere cancellata o meno. Ma non solo il pericolo delle eliminazioni è un motivo per cercare di dare una risposta "umana" ben formattata, ma aiuta anche molto se si desidera raccogliere voti positivi.
Peter dice di reintegrare Monica

2

Puoi provare a seguire il link http://www.lessfs.com/wordpress/ è un lavoro su COW (copia su scrittura) che farà risparmiare tempo e spazio


lessfs è molto interessante, ma è anche molto sperimentale. Non raccomandato per l'uso in produzione ancora.
mattdm,

2

Innanzitutto creare le directory solo sulla destinazione:

rsync -av --include '*/' --exclude '*' /source/ /destination/

Quindi collega solo i file:

cd /source
find . -type f -exec ln -v {} /destination/{} \;

Grazie - in realtà, potrei anche usare paxcome mostrato nel mio commento sopra, che sembra più facile.
Jean-Philippe Pellet,

1

Utilizzare l'opzione -H per conservare i collegamenti fisici e leggere la manpage.


1
-H non funziona. Non ho hardlink da preservare nel mio albero dei sorgenti, voglio solo una semplice copia del mio albero dei sorgenti dove nella copia, tutti i file sono collegati ai file originali. Scusa se la mia domanda originale non era chiara ...
Jean-Philippe Pellet,

"leggi la manpage" è una risposta? :-)
meduz
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.