Como extraio o conteúdo de uma rpm?


154

Eu tenho uma rotação e quero tratá-la como um tarball. Quero extrair o conteúdo em um diretório para que eu possa inspecionar o conteúdo. Eu estou familiarizado com os comandos de consulta de um pacote desinstalado. Eu não quero simplesmente uma lista do conteúdo das rpm. ie

$ rpm -qpl foo.rpm

Quero inspecionar o conteúdo de vários arquivos contidos nas rpm. Não quero instalar o rpm. Também estou ciente da capacidade do rpms de fazer modificações adicionais nas seções% post e como verificar essas alterações. ie

$ rpm -qp --scripts foo.rpm

No entanto, neste caso, isso não me interessa.

Respostas:


184

Você tentou o rpm2cpiocomando? Veja o exemplo abaixo:

$ rpm2cpio php-5.1.4-1.esp1.x86_64.rpm | cpio -idmv

/etc/httpd/conf.d/php.conf  
./etc/php.d  
./etc/php.ini  
./usr/bin/php  
./usr/bin/php-cgi  
etc 

28
Estou surpreso que as distribuições Linux não forneçam um wrapper executável para facilitar isso (por exemplo, rpmextract bla.rpm), pois essa é uma operação muito comum. O usuário não precisa se preocupar com o formato intermediário do cpio.
Alan Evangelista

2
Não se surpreenda, @AlanEvangelista, este é o par para o curso.
ngreen 30/10

isso precisa de acesso root para instalar o rpm2cpio :(
törzsmókus

9
@AlanEvangelista Estou impressionado que o rpm seja um formato tão ruim. Comparando com outros deb, que são apenas arquivos simples que aderem à filosofia do UNIX.
Trismegistos 03/03

1
@SumitMurari Claro que é ruim. Eu estava apenas oferecendo uma solução para a situação de törzsmókus.
MirroredFate

66
$ mkdir packagecontents; cd packagecontents
$ rpm2cpio ../foo.rpm | cpio -idmv
$ find . 

Para referência: os argumentos cpio são

-i = extract
-d = make directories
-m = preserve modification time
-v = verbose

Encontrei a resposta aqui: resposta de lontar


1
"rpm2cpio foo.rpm | cpio -idmv" funciona para mim. É suficiente extrair o conteúdo das rpm no caminho atual.
parasita

32

Para aqueles que não possuem o rpm2cpio, aqui está o antigo script rpm2cpio.sh que extrai a carga útil de um pacote * .rpm.

Republicado para a posteridade ... e para a próxima geração.

Invoque assim: ./rpm2cpio.sh .rpm | cpio -dimv

#!/bin/sh

pkg=$1
if [ "$pkg" = "" -o ! -e "$pkg" ]; then
    echo "no package supplied" 1>&2
    exit 1
fi

leadsize=96
o=`expr $leadsize + 8`
set `od -j $o -N 8 -t u1 $pkg`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
# echo "sig il: $il dl: $dl"

sigsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $sigsize + \( 8 - \( $sigsize \% 8 \) \) \% 8 + 8`
set `od -j $o -N 8 -t u1 $pkg`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
# echo "hdr il: $il dl: $dl"

hdrsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $hdrsize`
EXTRACTOR="dd if=$pkg ibs=$o skip=1"

COMPRESSION=`($EXTRACTOR |file -) 2>/dev/null`
if echo $COMPRESSION |grep -q gzip; then
        DECOMPRESSOR=gunzip
elif echo $COMPRESSION |grep -q bzip2; then
        DECOMPRESSOR=bunzip2
elif echo $COMPRESSION |grep -iq xz; then # xz and XZ safe
        DECOMPRESSOR=unxz
elif echo $COMPRESSION |grep -q cpio; then
        DECOMPRESSOR=cat
else
        # Most versions of file don't support LZMA, therefore we assume
        # anything not detected is LZMA
        DECOMPRESSOR=`which unlzma 2>/dev/null`
        case "$DECOMPRESSOR" in
            /* ) ;;
            *  ) DECOMPRESSOR=`which lzmash 2>/dev/null`
             case "$DECOMPRESSOR" in
                     /* ) DECOMPRESSOR="lzmash -d -c" ;;
                     *  ) DECOMPRESSOR=cat ;;
                 esac
                 ;;
        esac
fi

$EXTRACTOR 2>/dev/null | $DECOMPRESSOR

Eu recebo este erro "unlzma: cabeçalho ruim de lzma" usando o Alpine Linux. Tentei várias rpms.
precisa saber é

27

Às vezes, você pode encontrar um problema no arquivo RPM intermediário:

cpio: número malformado
cpio: número malformado
cpio: número malformado
. . .
cpio: final prematuro do arquivo

Isso significa que pode ser compactado; atualmente, é a compressão LZMA2, como de costume, por xz:

rpm2cpio <file>.rpm | xz -d | cpio -idmv

caso contrário, você pode tentar:

rpm2cpio <file>.rpm | lzma -d | cpio -idmv

2
Acabei de encontrar isso. Obrigado!
Sam Stoelinga

2
Muito útil. Obrigado senhor!
ILIV 9/09/15

1
salva-vidas. @LasseHalbergHaarbye adicionei-o à resposta aceita.
Joseph Farah

Eu estava recebendo os erros "Número incorreto" e "Fim prematuro do arquivamento", mas nenhuma das soluções postadas funcionou para mim. Eu tinha que fazer rpm2cpio <file>.rpm | bsdtar -xf -(sem cpio) para que funcionasse.
precisa saber é o seguinte

O arquivo intermediário acabou sendo formatado com gzip, então eu usei em gunzipvez de xzou lzmaque funcionou bem.
Jayhendren #

9

A maioria das distribuições instalou o rolo de arquivos do aplicativo GUI , que descompacta tar, zip, rpm e muito mais.

file-roller --extract-here package.rpm

Isso extrairá o conteúdo no diretório atual.



5

Você pode simplesmente fazer tar -xvf <rpm file>o mesmo!


Não foi possível reproduzir isso com um pacote .rpm. Você pode corrigir sua resposta.
Gvlasov

9
Isso funciona no OS X - ou em qualquer outro sistema que use uma variante tarusada libarchivesob o capô.
Glenjamin 01/12/2015

2
Eu recebi o erro: Isso não parece um arquivo tar.
Wp-overwatch.com 13/04/19

Isso funcionou para mim no MacOS 10.14.1 com o bsdtar 2.8.3 - libarchive 2.8.3. Pode depender de qual tipo de compactação foi usado. O script rpm2cpio.sh parece verificar vários tipos de compactação antes de passá-lo para a ferramenta correta para extração.
2xj

Como a funcionalidade de edição do SO não me permite adicionar 3 caracteres para corrigir a resposta, deve-se acrescentar que isso requer libarchive bsdtar. O Homebrew no Mac vincula tara ele por padrão, mas em outros sistemas operacionais tarsignifica GNU tar.
Atemu 18/09/19

5

O poderoso gerenciador de arquivos mc baseado em texto (Midnight Commander, lembrando vagamente o Norton Commander dos velhos tempos do DOS) tem o recurso interno de inspecionar e descompactar arquivos .rpm e .rpms, apenas "abra" o arquivo .rpm (s) dentro de mc e selecione CONTENTS.cpio: para um rpm você obtém acesso à árvore de instalação, para um rpms você obtém acesso ao arquivo .spec e a todos os pacotes de origem.




1

No OpenSuse, pelo menos, o unrpmcomando vem com o buildpacote.

Em um diretório adequado (porque esta é uma bomba de arquivo morto):

unrpm file.rpm

1

Copie o arquivo .rpm em uma pasta separada e execute o seguinte comando $ yourfile.rpm | cpio -idmv


esta deve ser comentário
ketan

1

O teste "DECOMPRESSION" falha no CygWin, uma das plataformas mais potencialmente úteis para ele, devido à verificação "grep" de "xz" que diferencia maiúsculas de minúsculas. O resultado da verificação "COMPRESSION:" é:

COMPRESSION='/dev/stdin: XZ compressed data'

Simplesmente substituir 'grep -q' por 'grep -q -i' em todos os lugares parece resolver bem o problema.

Fiz algumas atualizações, particularmente adicionando alguns comentários e usando "case" em vez de instruções "if" empilhadas, e incluí essa correção abaixo

#!/bin/sh
#
# rpm2cpio.sh - extract 'cpio' contents of RPM
#
# Typical usage: rpm2cpio.sh rpmname | cpio -idmv
#

if [ "$# -ne 1" ]; then
    echo "Usage: $0 file.rpm" 1>&2
    exit 1
fi

rpm="$1"
if [ -e "$rpm" ]; then
    echo "Error: missing $rpm"
fi


leadsize=96
o=`expr $leadsize + 8`
set `od -j $o -N 8 -t u1 $rpm`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
# echo "sig il: $il dl: $dl"

sigsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $sigsize + \( 8 - \( $sigsize \% 8 \) \) \% 8 + 8`
set `od -j $o -N 8 -t u1 $rpm`
il=`expr 256 \* \( 256 \* \( 256 \* $2 + $3 \) + $4 \) + $5`
dl=`expr 256 \* \( 256 \* \( 256 \* $6 + $7 \) + $8 \) + $9`
# echo "hdr il: $il dl: $dl"

hdrsize=`expr 8 + 16 \* $il + $dl`
o=`expr $o + $hdrsize`
EXTRACTOR="dd if=$rpm ibs=$o skip=1"

COMPRESSION=`($EXTRACTOR |file -) 2>/dev/null`
DECOMPRESSOR="cat"

case $COMPRESSION in
    *gzip*|*GZIP*)
        DECOMPRESSOR=gunzip
        ;;
    *bzip2*|*BZIP2*)
        DECOMPRESSOR=bunzip2
        ;;
    *xz*|*XZ*)
        DECOMPRESSOR=unxz
        ;;
    *cpio*|*cpio*)
        ;;
    *)
        # Most versions of file don't support LZMA, therefore we assume
        # anything not detected is LZMA
        DECOMPRESSOR="`which unlzma 2>/dev/null`"
        case "$DECOMPRESSOR" in
            /*)
                DECOMPRESSOR="$DECOMPRESSOR"
                ;;
            *)
                DECOMPRESSOR=`which lzmash 2>/dev/null`
                case "$DECOMPRESSOR" in
                    /* )
                        DECOMPRESSOR="lzmash -d -c"
                        ;;
                    *  )
                        echo "Warning: DECOMPRESSOR not found, assuming 'cat'" 1>&2
                        ;;
                esac
                ;;
        esac
esac

$EXTRACTOR 2>/dev/null | $DECOMPRESSOR

1

O 7-Zip é capaz de extrair o conteúdo. Funciona da mesma maneira que um arquivo tar.gz. Um arquivo compactado dentro de um arquivo compactado.

No Windows 7 Pro com o 7-Zip instalado:

Clique com o botão direito do mouse no arquivo rpm. Passe o mouse sobre o 7-Zip no menu de contexto. Selecione extrair para "nome do arquivo".

Entre na pasta nome do arquivo.

Clique com o botão direito do mouse no arquivo cpio. Passe o mouse sobre o 7-Zip no menu de contexto. Selecione extrair para "nome do arquivo".

Você terminou. A pasta com "nome do arquivo" contém o conteúdo extraído para inspeção.

Eu sei que vocês do Linux desprezam que as coisas sejam facilitadas, mas a longo prazo, se você tiver que gastar algum tempo procurando uma solução para um problema simples como esse; essa ineficiência está lhe custando dinheiro.

Dado o fato de vocês Linux desprezarem a simplicidade eficiente, duvido muito que a versão Linux do 7-Zip faça a mesma coisa da mesma maneira.

Por que facilitar quando você pode tornar completamente estúpido e afirmar ser um gênio ao mesmo tempo?

Só para ficar claro; Eu não sou um fanboy do Windows. Na verdade, estou pensando em mudar para o Linux. Eu simplesmente não pude resistir à oportunidade de passar o que os desenvolvedores do Windows considerariam bom senso, as melhores práticas de desenvolvedor em seus rostos.

Apenas fique feliz por eu estar postando isso e você não tem Mark Harmon ao seu lado; O agente especial Leroy Jethro Gibbs teria dado um tapa na cabeça por não usar a cabeça.

Não sei qual é a regra de Gibbs, mas a regra é: não torne as coisas mais difíceis para você do que elas precisam ser.

Agora vamos ver quem precisa tirar férias. Cuidar!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.