Distribution de scripts: empacotamento e instalação
1. Fundamentos da Distribuição de Scripts Bash
Distribuir um script Bash vai muito além de compartilhar um arquivo. Envolve considerar dependências (como jq, curl, bc), o runtime (geralmente /bin/bash ou /usr/bin/env bash) e a portabilidade entre distribuições Linux e até mesmo macOS.
1.1 Estrutura de diretórios recomendada
Um projeto bem organizado segue esta estrutura:
meu-script/
├── bin/
│ └── meu-script
├── man/
│ └── man1/
│ └── meu-script.1
├── lib/
│ └── funcoes.sh
├── tests/
│ └── test_meu-script.sh
├── Makefile
├── README.md
└── LICENSE
1.2 Padrões FHS e locais de instalação
O Filesystem Hierarchy Standard (FHS) define locais apropriados:
/usr/local/bin— para scripts instalados manualmente pelo administrador/opt/<nome-do-pacote>/— para pacotes autocontidos~/.local/bin— para instalação por usuário (sem privilégios root)
2. Empacotamento Manual com make install
2.1 Criando um Makefile
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
MANDIR ?= $(PREFIX)/share/man/man1
DESTDIR ?=
.PHONY: install uninstall checksum
install:
install -d $(DESTDIR)$(BINDIR)
install -d $(DESTDIR)$(MANDIR)
install -m 755 bin/meu-script $(DESTDIR)$(BINDIR)/
install -m 644 man/man1/meu-script.1 $(DESTDIR)$(MANDIR)/
uninstall:
rm -f $(DESTDIR)$(BINDIR)/meu-script
rm -f $(DESTDIR)$(MANDIR)/meu-script.1
checksum:
sha256sum bin/meu-script > checksums.sha256
2.2 Variáveis de instalação
# Instalação para diretório do usuário
make install PREFIX=~/.local
# Instalação em diretório temporário (para empacotamento)
make install DESTDIR=/tmp/meu-pacote
2.3 Geração de checksum
sha256sum bin/meu-script > meu-script.sha256
sha256sum -c meu-script.sha256
3. Empacotamento para Gerenciadores de Pacotes
3.1 Construção de pacotes .deb
Estrutura necessária:
meu-script_1.0/
├── DEBIAN/
│ ├── control
│ ├── preinst
│ └── postinst
└── usr/
└── local/
└── bin/
└── meu-script
Arquivo DEBIAN/control:
Package: meu-script
Version: 1.0
Section: utils
Priority: optional
Architecture: all
Depends: bash (>= 4.0), jq, curl
Maintainer: Seu Nome <email@exemplo.com>
Description: Ferramenta de automação em Bash
Script para gerenciamento de tarefas de DevOps.
Construção:
dpkg-deb --build meu-script_1.0
3.2 Construção de pacotes .rpm
Arquivo .spec:
Name: meu-script
Version: 1.0
Release: 1
Summary: Ferramenta de automação em Bash
License: MIT
Source: %{name}-%{version}.tar.gz
BuildArch: noarch
Requires: bash >= 4.0, jq, curl
%description
Script para gerenciamento de tarefas de DevOps.
%install
mkdir -p %{buildroot}/usr/local/bin
install -m 755 bin/meu-script %{buildroot}/usr/local/bin/
%files
/usr/local/bin/meu-script
Construção:
rpmbuild -ba meu-script.spec
3.3 Scripts de pré/pós-instalação
#!/bin/bash
# postinst - executado após instalação
if ! command -v jq &> /dev/null; then
echo "AVISO: jq não está instalado. Instale com: apt install jq"
fi
4. Distribuição via Repositórios Git e Tarballs
4.1 Versionamento semântico e tags
git tag -a v1.0.0 -m "Versão 1.0.0 - Lançamento inicial"
git push origin v1.0.0
4.2 Geração de tarballs assinados
git archive --format=tar.gz --prefix=meu-script-1.0/ v1.0.0 > meu-script-1.0.tar.gz
gpg --sign --detach-sign meu-script-1.0.tar.gz
sha256sum meu-script-1.0.tar.gz > meu-script-1.0.tar.gz.sha256
4.3 Scripts de instalação "one-liner"
curl -fsSL https://exemplo.com/install.sh | bash
Riscos: esse método permite execução de código arbitrário sem verificação. Mitigação:
curl -fsSL https://exemplo.com/install.sh -o install.sh
sha256sum -c install.sh.sha256 && bash install.sh
5. Empacotamento com Ferramentas Especializadas
5.1 Uso de shar (shell archive)
shar bin/meu-script lib/funcoes.sh > meu-script.shar
chmod +x meu-script.shar
./meu-script.shar # auto-extração
5.2 Empacotamento com makeself
makeself --gzip --sha256 ./meu-script-dir \
meu-script-installer.run \
"Instalador do Meu Script" \
./bin/meu-script --install
5.3 Alternativa: AppImage para scripts
Embora AppImage seja mais comum para aplicações gráficas, é possível empacotar scripts Bash usando appimagetool com um runtime mínimo.
6. Instalação e Atualização Automatizada
6.1 Script de auto-atualização
#!/bin/bash
VERSION="1.0.0"
REMOTE_URL="https://exemplo.com/meu-script-latest"
LOCAL_BIN="/usr/local/bin/meu-script"
check_update() {
local remote_version=$(curl -fsSL "$REMOTE_URL/version.txt")
if [ "$remote_version" != "$VERSION" ]; then
echo "Nova versão disponível: $remote_version"
curl -fsSL "$REMOTE_URL/meu-script" -o /tmp/meu-script-new
sha256sum -c "$REMOTE_URL/meu-script.sha256" && \
install -m 755 /tmp/meu-script-new "$LOCAL_BIN"
fi
}
6.2 Gerenciamento de dependências
#!/bin/bash
check_deps() {
local deps=("jq" "curl" "bc" "git")
local missing=()
for dep in "${deps[@]}"; do
if ! command -v "$dep" &> /dev/null; then
missing+=("$dep")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
echo "Dependências ausentes: ${missing[*]}"
echo "Instale com: sudo apt install ${missing[*]}"
exit 1
fi
}
6.3 Rollback e desinstalação
#!/bin/bash
uninstall() {
local files=(
"/usr/local/bin/meu-script"
"/usr/local/share/man/man1/meu-script.1"
"/etc/meu-script/config.cfg"
)
for file in "${files[@]}"; do
if [ -f "$file" ]; then
rm -i "$file"
fi
done
# Limpeza de PATH e variáveis de ambiente
sed -i '/meu-script/d' ~/.bashrc
echo "Desinstalação concluída."
}
7. Boas Práticas de Segurança na Distribuição
7.1 Assinatura digital com GPG
# Gerar chave
gpg --full-generate-key
# Assinar script
gpg --detach-sign --armor meu-script
# Verificar assinatura
gpg --verify meu-script.asc meu-script
7.2 Validação de checksums
#!/bin/bash
validate_package() {
local url="$1"
local checksum_url="$2"
local temp_file=$(mktemp)
curl -fsSL "$url" -o "$temp_file"
curl -fsSL "$checksum_url" -o "$temp_file.sha256"
if sha256sum -c "$temp_file.sha256" --status; then
echo "Checksum válido. Executando instalação..."
bash "$temp_file"
else
echo "ERRO: Checksum inválido! Pacote corrompido ou adulterado."
exit 1
fi
}
7.3 Sanitização de entradas
#!/bin/bash
sanitize_input() {
local input="$1"
# Remove caracteres perigosos
input="${input//[^a-zA-Z0-9_\/.-]/}"
echo "$input"
}
# Uso seguro
read -r user_input
safe_input=$(sanitize_input "$user_input")
8. Casos de Uso e Exemplos Práticos
8.1 Distribuição via curl | bash com fallback seguro
#!/bin/bash
# Script de instalação seguro
set -euo pipefail
INSTALLER_URL="https://exemplo.com/meu-script/install.sh"
CHECKSUM_URL="https://exemplo.com/meu-script/install.sh.sha256"
GPG_SIG_URL="https://exemplo.com/meu-script/install.sh.asc"
# Download com verificação
curl -fsSL "$INSTALLER_URL" -o /tmp/install.sh
curl -fsSL "$CHECKSUM_URL" -o /tmp/install.sh.sha256
curl -fsSL "$GPG_SIG_URL" -o /tmp/install.sh.asc
# Verificação GPG
gpg --verify /tmp/install.sh.asc /tmp/install.sh || {
echo "Falha na verificação GPG!"
exit 1
}
# Verificação SHA256
sha256sum -c /tmp/install.sh.sha256 || {
echo "Falha na verificação SHA256!"
exit 1
}
# Execução segura
bash /tmp/install.sh
8.2 Pacote .deb para ferramenta DevOps
#!/bin/bash
# Construção automatizada de pacote .deb
VERSION="1.0.0"
PACKAGE_NAME="meu-script_${VERSION}_all.deb"
# Preparar estrutura
mkdir -p build/DEBIAN
mkdir -p build/usr/local/bin
# Copiar script
cp bin/meu-script build/usr/local/bin/
chmod 755 build/usr/local/bin/meu-script
# Criar arquivo control
cat > build/DEBIAN/control << EOF
Package: meu-script
Version: $VERSION
Section: utils
Priority: optional
Architecture: all
Depends: bash (>= 4.0), jq, curl
Maintainer: DevOps Team <devops@exemplo.com>
Description: Ferramenta interna de automação
Script para deploy e monitoramento de serviços.
EOF
# Construir pacote
dpkg-deb --build build "$PACKAGE_NAME"
echo "Pacote gerado: $PACKAGE_NAME"
8.3 Integração com CI/CD
#!/bin/bash
# .github/workflows/release.yml (GitHub Actions)
name: Release
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build package
run: |
make build
make deb
make rpm
- name: Generate checksums
run: |
sha256sum *.deb *.rpm > checksums.txt
- name: Sign artifacts
run: |
gpg --detach-sign --armor *.deb
gpg --detach-sign --armor *.rpm
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: |
*.deb
*.rpm
checksums.txt
*.asc
Referências
- GNU Make Manual — Documentação oficial do Make, essencial para criar Makefiles de instalação
- Debian Packaging Guide — Guia oficial da Debian para criação de pacotes .deb
- RPM Packaging Guide — Tutorial completo da Red Hat para empacotamento RPM
- Filesystem Hierarchy Standard (FHS) — Padrão oficial de estrutura de diretórios em sistemas Linux
- GNU Privacy Guard (GPG) Documentation — Documentação oficial do GPG para assinatura digital de arquivos
- makeself - Self-extracting archives — Ferramenta para criar instaladores auto-contidos em shell script
- Shell Archive (shar) Manual — Documentação do GNU sharutils para criação de archives auto-extraíveis
- AppImage Documentation — Guia oficial do formato AppImage para distribuição de aplicações
- GitHub Actions Documentation — Documentação para automação de CI/CD e publicação de releases
- OWASP Command Injection Prevention — Guia de segurança para evitar injeção de comandos em scripts