Rinomina la directory all'interno di un archivio tar


14

È possibile rinominare una directory all'interno di un archivio tar? Il mio caso d'uso è che ho un file di specifiche RPM fornito esternamente che assume un tarball con una determinata struttura di directory e ho un tarball fornito esternamente il cui nome di directory di livello superiore non corrisponde a quello che si aspetta il file di specifiche. Non controllo né lo script che genera i tarball né il file delle specifiche RPM, quindi non posso apportare modifiche a nessuno di questi per corrispondere all'altro.

Quello che ho fatto è di non distrarre, cambiare il nome della directory e quindi creare un nuovo tarball, ma mi chiedevo se ci fosse un'alternativa a farlo.


3
Purtroppo ne dubito, ma sarei interessato a vedere se qualcun altro ha un modo. Penso che la tua scommessa migliore sia scrivere una sceneggiatura per decomprimere, rinominare e ri-tarare.
Kevin,

Risposte:


8

Non dovrebbe essere molto difficile, almeno per gli archivi compatibili con il formato vecchio stile in cui i nomi dei file sono memorizzati in un campo di dimensioni fisse (100 byte), ma non conosco alcuno strumento che possa rinominare un file in atto in un archivio tar. Inoltre, con un archivio compresso, dovresti comunque creare un nuovo file.

Dovrebbe essere ancora più semplice, ma non conosco alcuno strumento esistente in grado di filtrare un archivio, rinominando i file così come sono. Puoi costruirne uno sopra le librerie tar nei linguaggi di scripting; per esempio, ecco uno script di prova di concetto per rinominare una directory in un archivio tar usando Perl conArchive::Tar . L'archivio viene caricato interamente in memoria; questa è una limitazione intrinseca di Archive::Tar.

#!/usr/bin/env perl
## Usage: tar-rename OLDPREFIX NEWPREFIX
use strict;
use warnings;
use Archive::Tar;
my ($from, $to) = @ARGV;
my $tar = Archive::Tar->new(\*STDIN);
foreach my $file ($tar->get_files()) {
    my $name = $file->name;
    $name =~ s~\A\Q$from\E($|/)~$to$1~;
    $file->rename($name) unless $name eq $file->name;
}
$tar->write(\*STDOUT);

Tar Tar GNU non ha la possibilità di rinominare i membri al volo, ma pax(sostituzione di POSIX per cpioe tar). Tuttavia, non è possibile paxsia leggere che scrivere da un archivio. Quello che puoi fare è esporre l'archivio come un normale albero tramite AVFS e creare un nuovo archivio con pax. Ciò conserva i nomi dei file (tranne quelli trasformati), i contenuti, i tempi e le modalità ma reimposta la proprietà dei file (a meno che non venga eseguita come root).

mountavfs
cd "~/.avfs$PWD/old.tgz#"
pax -w -s '!bar!baz!' -s '!bar/!baz/' . | gzip >new.tgz

GNU Tar ha avuto --transformalmeno dal 2010 che consente di rinominare i file al volo. Per un esempio, vedi: scriptsandoneliners.blogspot.com/2019/11/…
A.Danischewski

@ A.Danischewski --transformti consente di rinominare i file quando compili o estrai un archivio. Ma come si fa a rinominare i file in un archivio senza estrarlo? (L'estrazione non è una buona soluzione: potresti non avere abbastanza spazio su disco; potresti non avere le autorizzazioni per conservare le informazioni sulla proprietà; potresti non avere la capacità di conservare esattamente i timestamp ...)
Gilles 'SO- smetti di essere malvagio'

Ok, sì, ho appena visto il tuo post che afferma che "GNU tar non ha la capacità di rinominare i membri al volo", ma solo in entrata / uscita. Se si desidera modificare i nomi all'interno di un archivio esistente, è possibile utilizzare archivemount per montarlo su una directory, modificare i nomi desiderati e smontarlo.
A.Danischewski,

3

Sia l'hack di sr_ che la risposta di Gilles sembrano molto buoni, ma se il tuo problema è solo il nome della directory radice del tarball di destinazione, mentre esegui rpmbuild, una soluzione diversa potrebbe essere quella di ridefinire la %setupmacro per fare la rinomina di directory necessaria.

Qualcosa di simile (si dovrà adattare e perfezionare questo per la configurazione attuale, in particolare la sostituzione old-dired desired-dire usando lo strumento di decompressione a destra) questo nel vostro ~/.rpmmacros:

%setup cd ../BUILD \
rm -rf cd-player \
bunzip2 -dc ../SOURCES/%{name}-%{version}.tar.bz2 | tar -xvvf - \
if [ $? -ne 0 ]; then \
  exit $? \
fi \
mv <old-dir> <desired-dir> \
cd <desired-dir> \
cd ../BUILD/cd-player \
chmod -R a+rX,g-w,o-w .

Onestamente non lo farei se non nella situazione più esotica, ma il tuo potrebbe essere il caso :)



1

Brutto hack, ma forse questo ti aiuta, prendendo in targiro i link simbolici:

$ mkdir a b
$ date >> b/foo
$ tar zcvf b-foo.tgz b/foo
$ rm -rf b
$ ln -s a b

$ tar zxvf b-foo.tgz                                                              
x b/foo: Cannot extract through symlink b
tar: Error exit delayed from previous errors.
$ tar zxvPf b-foo.tgz                                                             
x b/foo
$ ls a
foo

Pensandoci, probabilmente non lo farà, poiché rpmnon ti lascerà incasinare gli argomenti tar, vero? (Modifica: forse un po 'di tarscript wrapper complicato $PATHpotrebbe farti aggirare questo.)

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.