Tarare una directory, ma non archiviare i percorsi assoluti completi nell'archivio


277

Ho il seguente comando nella parte di uno script della shell di backup:

tar -cjf site1.bz2 /var/www/site1/

Quando elenco i contenuti dell'archivio, ottengo:

tar -tf site1.bz2
var/www/site1/style.css
var/www/site1/index.html
var/www/site1/page2.html
var/www/site1/page3.html
var/www/site1/images/img1.png
var/www/site1/images/img2.png
var/www/site1/subdir/index.html

Ma vorrei rimuovere la parte /var/www/site1dalla directory e dai nomi dei file all'interno dell'archivio, al fine di semplificare l'estrazione ed evitare la struttura di directory costante inutile. Non lo so mai, nel caso in cui estrarrei siti Web di backup in un luogo in cui i dati Web non erano archiviati /var/www.

Per l'esempio sopra, vorrei avere:

tar -tf site1.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html

Quindi, quando estraggo, i file vengono estratti nella directory corrente e non ho bisogno di spostare i file estratti in seguito, e così vengono preservate le strutture della sottodirectory.

Esistono già molte domande su tar e il backup in stackoverflowe in altri punti del Web, ma la maggior parte di essi richiede di eliminare l'intera struttura della sottodirectory (appiattimento) o semplicemente aggiungere o rimuovere l'iniziale / nei nomi (non non so cosa cambia esattamente durante l'estrazione), ma non di più.

Dopo aver letto alcune delle soluzioni trovate qua e là e il manuale, ho provato:

tar -cjf site1.bz2 -C . /var/www/site1/
tar -cjf site1.bz2 -C / /var/www/site1/
tar -cjf site1.bz2 -C /var/www/site1/ /var/www/site1/
tar -cjf site1.bz2 --strip-components=3 /var/www/site1/

Ma nessuno di loro ha funzionato come voglio. Alcuni non fanno nulla, altri non archiviano più le sottodirectory.

È all'interno di uno script della shell di backup avviato da Cron, quindi non so bene quale utente lo esegue, qual è il percorso e la directory corrente, quindi è sempre necessario scrivere il percorso assoluto per tutto e preferirei non cambiare la directory corrente per evitare di rompere qualcosa di più nello script (perché non solo esegue il backup di siti Web, ma anche di database, quindi invia tutto ciò a FTP ecc.)

Come raggiungere questo obiettivo?

Ho appena frainteso come funziona l'opzione -C?



Bene, -Csignifica solo "cambia directory", mentre la sostituzione di un percorso (o prefisso) può essere eseguita solo da --transform. rif. superuser.com/questions/595510/prepend-prefix-in-tar/595512 puoi semplicemente -C (cambiare directory) e - trasformarlo: `` tar cjf site1.bz2 --transform "s / ^ \. \ // $ targetbase / "-C / var / www / site1. ``
Daniele Cruciani,

Questa è un'ottima domanda e purtroppo nessuna delle risposte a questa data è soddisfacente. Dobbiamo ancora sentire da una persona saggia come possiamo eventualmente estrarre solo il singolo file style.css (esempio sopra) nella directory corrente senza alcun riferimento alla posizione originale o all'albero delle directory? Non voglio ingombrare la mia directory corrente con una nuova struttura ad albero indesiderata. Sembra una grave carenza di tarball che è stata ignorata per anni.
elmclose l'

Risposte:


383
tar -cjf site1.tar.bz2 -C /var/www/site1 .

Nell'esempio sopra, tar passerà alla directory /var/www/site1prima di fare le sue cose perché è -C /var/www/site1stata data l'opzione .

Da man tar:

OTHER OPTIONS

  -C, --directory DIR
       change to directory DIR

152
Non perdere il punto alla fine, è importante ;-)
Freedom_Ben

9
che ne dici se vuoi anche selezionare i file per il backup in base a un carattere jolly? -C / var / www / site1 * .dat non funziona :(
Andy Lorenz,

16
Il punto dice tardi archiviare tutto nella directory corrente. E -Cimposta la directory corrente.
Lars Brinkhoff,

21
Funziona benissimo. Trovo utile preservare il nome della directory (ma non il percorso completo), quindi ho fatto quanto segue: tar -czvf site1.tar.gz -C /var/www/ site1(Nota lo spazio, sto ancora usando -C, per cd alla directory principale e specificando la directory su tar invece di punto)
jorfus

9
Ottengo un punto iniziale nel percorso del tar, ad es. ./foldersCome può essere rimosso?
Mika571,

39

L'opzione -Cfunziona; solo per chiarimenti posterò 2 esempi:

  1. creazione di un tarball senza il percorso completo: percorso completo /home/testuser/workspace/project/application.ware ciò che vogliamo è proprio project/application.warcosì:

    tar -cvf output_filename.tar  -C /home/testuser/workspace project

    Nota: c'è uno spazio tra workspacee project; tar sostituirà il percorso completo con just project.

  2. estrazione di tarball con modifica del percorso target (impostazione predefinita su ., ovvero directory corrente)

    tar -xvf output_filename.tar -C /home/deploy/

    tarestrarrà tarball in base al percorso specificato e preservando il percorso di creazione; nel nostro esempio il file application.warverrà estratto /home/deploy/project/application.war.

    /home/deploy: dato su estratto
    project: dato su creazione di tarball

Nota: se si desidera posizionare il tarball creato in una directory di destinazione, è sufficiente aggiungere il percorso di destinazione prima del nome tarball. per esempio:

tar -cvf /path/to/place/output_filename.tar  -C /home/testuser/workspace project

1
come aggiungere caratteri jolly per la selezione dei file nell'ultimo esempio?
Siva,

Il problema con i caratteri jolly è che la shell li espande ai nomi dei file corrispondenti e che tar non li espande se vengono citati ...
Gert van den Berg,

Ho provato questo su Ubuntu 18.04 e senza fortuna. Non sono sicuro di cosa mi sto perdendo. Il mio stdout lo visualizza correttamente quando lo impacco, ma quando lo annullo, ha ancora il percorso completo
SDC

14

Sembra -Cche fino a tar v2.8.3 non funzioni in modo coerente su tutte le piattaforme (sistemi operativi). -Csi dice che aggiunge directory all'archivio ma su Mac e Ubuntu aggiunge un prefisso di percorso assoluto all'interno del file tar.gz generato.

tar target_path/file.tar.gz -C source_path/source_dir

Pertanto, la soluzione coerente e solida è quella cddi accedere a source_path (directory principale di source_dir) ed eseguire

tar target_path/file.tar.gz source_dir

o

tar -cf target_path/file.tar.gz source_dir

nella tua sceneggiatura. Ciò rimuoverà il prefisso del percorso assoluto nella struttura della directory del file tar.gz generato.


1
L'uso dell'opzione -C DID rimuove i prefissi di percorso assoluti all'interno del file tar.gz generato su fedora 29. La tua risposta è specifica per qualche sistema?
EL_DON

@EL_DON: Non ho testato l'opzione -C su Fedora, ma idealmente il software applicativo tar dovrebbe funzionare in modo coerente su ogni piattaforma a meno che non sia un bug nell'applicazione tar. -C opzione, ho testato su Mac 10.8 e Mac 10.13 e Ubuntu (versione che non ricordo). Ma a partire da tar v2.8.3, il comando è stato modificato in tar -cf target_path / file.tar.gz source_dir e comunque se si aggiunge l'opzione -C non rimuoverà il prefisso di percorso assoluto all'interno del file tar.gz generato.
Chinthaka Senanayaka,

Ho provato di nuovo su un sistema centOS. Dopo aver creato tutti i percorsi nell'esempio ed eseguito il comando (con l' -cvfaggiunta dopo tar), trovo che il file tar.gz risultante non abbia percorsi assoluti al suo interno, il che è coerente con molte altre risposte. Se ritieni che tar sia danneggiato o obsoleto su entrambi i sistemi che ho usato per i test, ti preghiamo di collegarti ad alcuni documenti che supportano la tua risposta. Penso che l' -Copzione cambi directory prima dell'esecuzione (come in altre risposte). Quando lo ometto, tar cerca di aggiungere junk da ./, inclusi i percorsi da cui partire ./.
EL_DON,

Ho usato questo documento: linux.die.net/man/1/tar Sì, il documento dice -C farebbe il cambio di percorso, ma sul mio Mac 10.13 non funziona. questo può essere un comportamento incoerente dell'app tar. Ciò significa che questo è un bug. Se stai scrivendo uno script di shell da eseguire su tutte le piattaforme unix, allora è meglio essere sicuri con l'esecuzione di codice che funzionerà su tutti i sistemi operativi.
Chinthaka Senanayaka,

La tua risposta non dice che potrebbe esserci un bug e la soluzione più solida per la compatibilità multipiattaforma è la cdprima. La tua risposta dice che lo strumento funziona in modo opposto a come dicono i documenti e come funziona sul mio sistema, quindi è una risposta sbagliata. Potresti risolverlo facilmente.
EL_DON,

7

Il seguente comando creerà una directory radice "." e inserire tutti i file dalla directory specificata in esso.

tar -cjf site1.tar.bz2 -C /var/www/site1 .

Se vuoi mettere tutti i file nella radice del file tar, @chinthaka ha ragione. Basta accedere alla directory e fare:

tar -cjf target_path/file.tar.gz *

Questo metterà tutti i file nel CDW nel file tar come file root.


1
L'uso di * non salva file .folder o .folder "nascosti". (a proposito, usando -C insieme a * non riesce, la shell espande la
directory

1

L'uso del "punto" porta alla creazione di una cartella denominata "punto" (su Ubuntu 16).

tar -tf site1.bz2 -C /var/www/site1/ .

L'ho affrontato in modo più dettagliato e ho preparato un esempio. Registrazione su più righe, oltre a un'eccezione.

tar -tf site1.bz2\
    -C /var/www/site1/ style.css\
    -C /var/www/site1/ index.html\
    -C /var/www/site1/ page2.html\
    -C /var/www/site1/ page3.html\
    --exclude=images/*.zip\
    -C /var/www/site1/ images/
    -C /var/www/site1/ subdir/
/

Perché lo chiami "punto"? È solo ., che è la directory corrente. Nel contesto della tar.gzstruttura di, questo è solo il livello base / root / top, giusto?
EL_DON

Vedi l'istantanea per l' immagine dei dettagli . La mia strada è più corretta da usare, è la mia opinione.
Sergey Asachev,

0

Se si desidera archiviare una sottodirectory e tagliare il percorso della sottodirectory, questo comando sarà utile:

tar -cjf site1.bz2 -C /var/www/ site1
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.