Extraindo arquivo pelo piping de conteúdo do arquivo no comando tar

2

Estou criando um arquivo de extração automática e tenho a coisa básica em andamento.

No entanto, quero definir o comando que extrai o conteúdo do arquivo   tail -n+$ARCHIVE_START_LINE $0 em uma variável. Eu não consigo fazer essa parte funcionar

Eu tentei muitas coisas aqui - uma é mostrada abaixo para explicação. (Observe que este é um exemplo simplificado e a questão é tanto sobre o entendimento de pipes, etc., quanto a solução do problema.)

#!/bin/bash
export TMPDIR='mktemp -d /tmp/selfextract.XXXXXX'
ARCHIVE_START_LINE='awk '/^__ARCHIVE_BELOW__/ {print NR + 1; exit 0; }' $0'

# This works...
tail -n+$ARCHIVE_START_LINE $0 | tar xzv -C $TMPDIR

# .. but this is the kind of thing I want. But it doesn't work...
ARCHIVE_CONTENTS='tail -n+$ARCHIVE_START_LINE $0'
echo $ARCHIVE_CONTENTS | tar xzv -C $TMPDIR
# I get: gzip: stdin is a multi-part gzip file -- not supported

Estou no Ubuntu 12.04

    
por spiderplant0 12.04.2015 / 14:38

3 respostas

2

Todos os seus problemas são explicados em Por que meu script de shell sufoca em espaços em branco ou outros caracteres especiais? , mas vou repetir as partes relevantes aqui.

Primeiro, $var em um script de shell não significa "o valor da variável var ", isso significa "pegar o valor da variável var , dividi-lo em palavras e interpretar cada palavra como um caractere curinga padronizar". Para evitar essas etapas extras, coloque aspas duplas em torno das substituições de variáveis: "$var" significa “o valor da variável var ”. Sempre coloque aspas duplas em torno de substituições de variáveis e substituições de comandos , a menos que você saiba e entenda por que precisa deixá-las de fora.

Segundo, echo não imprime exatamente seu argumento: ele interpreta algumas opções e, em alguns shells, interpreta sequências de escape de barra invertida. Além disso, echo imprime uma nova linha à direita, que você pode remover com a opção -n . Os dados compactados com gzps nunca são uma opção e o echo de bash trata as barras invertidas literalmente por padrão, mas, em geral, não use echo em dados desconhecidos, use printf %s .

printf %s "$ARCHIVE_CONTENTS" | tar xzv -C "$TMPDIR"

Isso garante o valor da variável ARCHIVE_CONTENTS a tar exatamente.

O problema restante, e um que você não pode resolver sem usar uma abordagem fundamentalmente diferente, é que a maioria das shells (todas as shells que eu vi separadas de zsh) truncam o valor das variáveis no primeiro byte nulo (isto é porque eles usam seqüências C terminadas por nulo sob o capô). Portanto, a variável ARCHIVE_CONTENTS na verdade contém apenas o início do archive, até o primeiro byte nulo. Você não pode usar um shell para manipular dados binários.

    
por 13.04.2015 / 02:20
1

por que não usar um documento aqui como nos velhos tempos?

 #!/bin/bash
 export TMPDIR='mktemp -d /tmp/selfextract.XXXXXX'

 ## other stuff

 base64 -d <<EOF | tar xvf -C $TMPDIR
 ## base64 encoded
 EOF

você produz codificação base64 dessa maneira

 tar cf - my_dir | base64 > /some/place

(incluindo o arquivo self-extract é deixado ao leitor)

    
por 12.04.2015 / 15:15
0

Você pode estar inadvertidamente expandindo o conteúdo do seu arquivo. Tente citar sua variável.

Substituir

echo $ARCHIVE_CONTENTS | tar xzv -C $TMPDIR

com

echo "$ARCHIVE_CONTENTS" | tar xzv -C $TMPDIR

Você também pode precisar evitar acrescentar uma nova linha com echo -n

    
por 12.04.2015 / 16:22

Tags