Assine a Lista Dicas-L
Receba diariamente por email as dicas
de informática publicadas neste site
Para se descadastrar, clique aqui.
Compactados auto-extratores com bash script e tar
Colaboração: Marcelo Criscuolo
Data de Publicação: 16 de Setembro de 2005
Recentemente me deparei com o problema de criar um arquivo compactado que fosse capaz de se "auto-descompactar" e realizar algumas outras "tarefinhas burocráticas". Lembrei-me então que o instalador do J2SDK da Sun para Linux é um shell script e resolvi descobrir como ele era feito. A solução é bem elegante e simples de ser implementada, trata-se de criar um arquivo composto por um shell script no início e o arquivo compactado (binário) no final.
Suponhamos que você deseja compactar todo o diretório
basedados que contém scripts SQL e enviá-lo para alguém
de maneira que seja necessário apenas um comando como
./atualizar-base.sh para o arquivo seja descompactado
e a base seja atualizada com base nos arquivos contidos
no diretório.
Para começar, o velho tar resolve a primeira parte
do problema:
tar cvzf basedados.tar.gz basedados/``
Agora precisamos do script que vai fazer o "trabalho sujo",
o atualizar-base-codigo.sh:
#!/bin/bash # extraindo o arquivo tail -n +XX $0 > basedados.tar.gz # linha IMPORTANTE # Descompactando o arquivo extraído tar xzf basedados.tar.gz # Arquivo descompactado, hora de rodar os scripts for i in basedados/*; do echo "Rodando o script $i" # Aqui você poderia rodar os scripts. Por exemplo, # se a base da dados fosse Postgres você poderia # fazer: psql -U usuario base -c "\i $i" , para # rodar todos os scripts do diretório done exit 0 # outra linha IMPORTANTE
É hora de fazer o nosso trabalho sujo agora:
Vamos contar as linhas do arquivo:
wc -l atualizar-base-codigo.sh``
Preste atenção às linhas marcadas com IMPORTANTE.
Nesse caso o wc retorna 18, re-edite o arquivo e
substitua o XX da primeira linha marcada como importante
por 19 (18+1), salve o arquivo sem adicionar mais nenhuma
linha. Vamos juntar tudo agora:
cat atualizar-base-codigo.sh basedados.tar.gz > atualizar-base.sh``
Pronto! Concatenamos um arquivo texto e um binário!
O tail extrai as linhas finais de um arquivo, mas
quando o número de linhas é precedido pelo sinal + ele
extrai todo o final do arquivo, daquela linha em diante
(veja man tail), é esse o papel do -n +19.
No nosso exemplo, o tail vai extrair o final do próprio
shell script (a variável $0 é expandida para o nome
do arquivo atual) a partir da linha 19, que corresponde ao
arquivo basedados.tar.gz contenado a ele anteriormente.
Por o último, o > basedados.tar.gz é responsável
por escrever a saída do tail num arquivo ao invés de
escrever na tela.
O arquivo é descompactado com o tar na linha seguinte
e o seu conteúdo é processado pelo for.
Finalmente, na segunda linha marcada com IMPORTANTE,
tem-se o exit 0; esse comando serve para dizer ao
bash que pare de interpretar o script antes de atingir
os dados binários.
Um aviso importante: não edite mais o arquivo gerado
pelo cat pois se o editor colocar um EOF no final
o seu arquivo compactado será corrompido. É por isso que
se usa o arquivo atualizar-base-codigo.sh para fazer
a edição.
Outra coisa legal que dá pra fazer com isso é gerar
patches auto-aplicáveis. Ao invés de concatenar o
arquivo com um compactado você concatena com a saída do
diff (o patch). Neste caso o exit 0 também
é essencial, pela mesma razão citada anteriormente, mas
agora o arquivo gerado pode ser editado, já que um EOF
a mais ou a menos não faz diferença para o patch. ;-)
Veja a relação completa dos artigos de Marcelo Criscuolo
Referências Adicionais
Referências adicionais sobre os assuntos abordados neste site podem ser encontradas em nossa Bibliografia.
Avalie esta dica
Opinião dos Leitores
09 Jul 2007, 14:29
simples e extremamente prática, bem na filosofia linux ...
Parabéns pela dica !









