DevOps

Linux

Comandos essenciais, shell scripting, processos, redes e administração de sistemas.

1. Navegação e Arquivos

ls — Listar diretórios

ls                        # listagem simples
ls -l                     # formato longo (permissões, dono, tamanho, data)
ls -la                    # inclui arquivos ocultos (dotfiles)
ls -lh                    # tamanhos legíveis (KB, MB, GB)
ls -lt                    # ordenar por data de modificação (mais recente primeiro)
ls -ltr                   # ordenar por data (mais antigo primeiro)
ls -lS                    # ordenar por tamanho (maior primeiro)
ls -R                     # listar recursivamente
ls -1                     # um arquivo por linha
ls --color=auto           # colorir output (ativo por padrão na maioria das distros)
ls -i                     # mostrar inode de cada arquivo
ls -d */                  # listar apenas diretórios

cd, pwd — Navegação

pwd                       # mostra o diretório atual
cd /etc                   # ir para caminho absoluto
cd ../..                  # subir dois níveis
cd -                      # voltar ao diretório anterior
cd ~                      # ir para o home do usuário atual
cd ~joao                  # ir para o home do usuário joao

find — Busca avançada

# Por nome
find /var/log -name "*.log"              # arquivos .log em /var/log
find . -iname "readme*"                  # case-insensitive
find /home -name ".bashrc"               # busca específica

# Por tipo
find /tmp -type f                        # apenas arquivos regulares
find /etc -type d                        # apenas diretórios
find . -type l                           # apenas symlinks

# Por tamanho
find / -size +100M                       # arquivos maiores que 100MB
find . -size -1k                         # arquivos menores que 1KB
find /var -size +50M -size -200M         # entre 50MB e 200MB

# Por data
find /home -mtime -7                     # modificados nos últimos 7 dias
find /tmp -mtime +30                     # modificados há mais de 30 dias
find . -newer /etc/passwd                # mais novos que o arquivo referência
find . -atime -1                         # acessados nas últimas 24h

# Com exec — executar comando sobre os resultados
find /tmp -name "*.tmp" -exec rm {} \;         # deletar todos .tmp
find . -name "*.sh" -exec chmod +x {} \;       # tornar scripts executáveis
find /var/log -name "*.log" -exec gzip {} \;   # comprimir todos os logs
find . -type f -exec grep -l "TODO" {} \;      # arquivos que contêm "TODO"

# Com -print0 e xargs para nomes com espaços
find . -name "*.jpg" -print0 | xargs -0 ls -lh

# Excluir diretórios da busca
find . -name node_modules -prune -o -name "*.js" -print

locate, which, whereis

locate nginx.conf                        # busca em banco de dados (rápido)
sudo updatedb                            # atualizar banco do locate
which python3                            # caminho do executável no PATH
which -a python                          # todos os python no PATH
whereis bash                             # binário, fontes e man pages

tree — Visualização em árvore

tree                                     # árvore do diretório atual
tree -L 2                                # apenas 2 níveis de profundidade
tree -a                                  # incluir arquivos ocultos
tree -d                                  # apenas diretórios
tree -h                                  # tamanhos legíveis
tree -I "node_modules|.git"             # excluir padrões
tree --dirsfirst                         # diretórios antes dos arquivos

du, df — Uso de disco

du -sh /var/log                          # tamanho total do diretório
du -sh *                                 # tamanho de cada item no diretório atual
du -h --max-depth=1 /home               # um nível de profundidade
du -ah | sort -rh | head -20            # top 20 maiores arquivos/diretórios

df -h                                    # espaço em disco de todos os filesystems
df -hT                                   # inclui tipo do filesystem
df -h /home                             # apenas o filesystem que contém /home
df -i                                    # uso de inodes

2. Manipulação de Arquivos e Texto

Operações básicas

# cp — copiar
cp arquivo.txt destino/                  # copiar arquivo
cp -r pasta/ destino/                    # copiar diretório recursivamente
cp -p arquivo.txt backup/                # preservar permissões e datas
cp -u src/* dest/                        # copiar apenas se mais novo
cp -v arquivo.txt destino/              # verbose (mostrar o que está sendo copiado)
cp -i arquivo.txt destino/              # perguntar antes de sobrescrever

# mv — mover/renomear
mv arquivo.txt novo_nome.txt            # renomear
mv *.log /var/log/                       # mover múltiplos arquivos
mv -i arquivo.txt destino/              # perguntar antes de sobrescrever
mv -n arquivo.txt destino/              # não sobrescrever se existir

# rm — remover
rm arquivo.txt                           # remover arquivo
rm -r pasta/                             # remover diretório recursivamente
rm -rf pasta/                            # forçar sem confirmação (cuidado!)
rm -i *.tmp                              # confirmar cada remoção
rm -v arquivo.txt                        # verbose

# mkdir — criar diretórios
mkdir novo_dir                           # criar diretório
mkdir -p /tmp/a/b/c                     # criar hierarquia completa
mkdir -m 755 publico/                   # criar com permissões específicas
mkdir dir1 dir2 dir3                    # criar múltiplos de uma vez

# touch — criar/atualizar timestamps
touch arquivo.txt                        # criar arquivo vazio ou atualizar data
touch -t 202312251200 arquivo.txt       # definir data específica (YYYYMMDDhhmm)
touch -r ref.txt target.txt             # copiar timestamps de ref para target

Visualização de conteúdo

# cat
cat arquivo.txt                          # exibir conteúdo
cat -n arquivo.txt                       # com números de linha
cat -A arquivo.txt                       # mostrar caracteres especiais
cat file1.txt file2.txt > merged.txt    # concatenar arquivos
cat > novo.txt                           # criar arquivo (CTRL+D para salvar)

# less — paginação interativa
less arquivo.txt                         # abrir para leitura
# Atalhos: q=sair, /termo=buscar, n=próximo, N=anterior, g=início, G=fim, F=seguir

# head e tail
head -20 arquivo.txt                     # primeiras 20 linhas
head -c 1k arquivo.txt                   # primeiros 1024 bytes
tail -30 arquivo.log                     # últimas 30 linhas
tail -f /var/log/syslog                  # seguir em tempo real
tail -f -n 100 app.log                  # últimas 100 linhas + seguir
tail -n +50 arquivo.txt                 # a partir da linha 50

# wc — contar
wc -l arquivo.txt                        # número de linhas
wc -w arquivo.txt                        # número de palavras
wc -c arquivo.txt                        # número de bytes
wc -m arquivo.txt                        # número de caracteres
wc arquivo.txt                           # linhas, palavras e bytes

Manipulação de texto

# sort
sort arquivo.txt                         # ordenar alfabeticamente
sort -r arquivo.txt                      # ordem reversa
sort -n numeros.txt                      # ordenar numericamente
sort -k2 tabela.txt                      # ordenar pelo campo 2
sort -k2 -n -r tabela.txt               # campo 2, numérico, decrescente
sort -t: -k3 -n /etc/passwd             # ordenar /etc/passwd por UID

# uniq — linhas únicas/duplicadas (requer input ordenado)
sort lista.txt | uniq                    # remover duplicatas
sort lista.txt | uniq -d                 # mostrar apenas duplicatas
sort lista.txt | uniq -u                 # mostrar apenas únicas
sort lista.txt | uniq -c                 # contar ocorrências

# cut — extrair colunas
cut -d: -f1 /etc/passwd                 # campo 1 delimitado por ':'
cut -d, -f2,4 dados.csv                 # campos 2 e 4 do CSV
cut -c1-10 arquivo.txt                  # primeiros 10 caracteres de cada linha
cut -d' ' -f1-3 frase.txt              # primeiras 3 palavras

# paste — juntar arquivos por colunas
paste file1.txt file2.txt               # colunas lado a lado (separado por tab)
paste -d, nomes.txt idades.txt          # separado por vírgula

# tr — transliterar/deletar caracteres
tr 'a-z' 'A-Z' < arquivo.txt           # converter para maiúsculas
tr -d '\n' < arquivo.txt                # remover newlines
tr -s ' ' < arquivo.txt                 # condensar espaços múltiplos
tr -d '[:punct:]' < texto.txt          # remover pontuação
echo "hello world" | tr ' ' '\n'       # trocar espaço por newline

# tee — redirecionar para arquivo E stdout
comando | tee saida.txt                  # salvar E exibir na tela
comando | tee -a saida.txt              # append ao arquivo
comando | tee saida.txt | grep erro     # filtrar o que vai para a tela

# xargs — passar stdin como argumentos
find . -name "*.txt" | xargs wc -l          # contar linhas em todos .txt
cat lista.txt | xargs -I{} mkdir {}          # criar diretórios da lista
find . -type f -name "*.log" | xargs gzip   # comprimir todos .log
echo "a b c" | xargs -n1 echo              # um argumento por linha
find . -name "*.py" | xargs -P4 pylint      # executar em paralelo (4 processos)

3. Grep e Expressões Regulares

grep básico e flags essenciais

grep "erro" arquivo.log                  # buscar padrão
grep -i "erro" arquivo.log              # case-insensitive
grep -r "TODO" ./src/                   # busca recursiva em diretório
grep -l "senha" /etc/*.conf             # apenas nomes dos arquivos com match
grep -n "function" script.js            # mostrar números de linha
grep -v "DEBUG" app.log                 # inverter (linhas que NÃO contêm)
grep -c "erro" arquivo.log             # contar linhas com match
grep -w "root" /etc/passwd             # palavra inteira (word boundary)
grep -x "root:.*" /etc/passwd          # linha inteira deve dar match
grep -m 5 "erro" app.log               # parar após 5 matches

# Contexto ao redor do match
grep -A 3 "Exception" app.log          # 3 linhas APÓS o match
grep -B 2 "Exception" app.log          # 2 linhas ANTES do match
grep -C 5 "Exception" app.log          # 5 linhas antes e depois

# Extended regex (-E ou egrep)
grep -E "erro|falha" app.log           # alternação (OR)
grep -E "^[0-9]{4}-" log.txt          # linhas começando com 4 dígitos e traço
grep -E "\b[A-Z]{2,}\b" texto.txt     # palavras todo maiúsculas
grep -E "https?://" urls.txt           # http ou https

# Perl regex (-P) — recursos mais avançados
grep -P "\d{3}\.\d{3}\.\d{3}-\d{2}" dados.txt  # CPF
grep -P "(?<=User: )\w+" log.txt               # lookbehind
grep -P "\b192\.168\.\d{1,3}\.\d{1,3}\b" /var/log/auth.log  # IPs internos

# Exemplos práticos
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn
# IPs com tentativas de login falhas

grep -rn "console.log" ./src --include="*.js"   # apenas arquivos .js
grep -rn "TODO\|FIXME\|HACK" ./src --color=always | less -R
# listar todos os comentários de pendências

grep -oP "(?<=href=\")[^\"]*" index.html        # extrair URLs de links HTML

4. Sed e Awk

sed — Stream Editor

# Substituição básica
sed 's/antigo/novo/' arquivo.txt         # substituir primeira ocorrência por linha
sed 's/antigo/novo/g' arquivo.txt        # substituir todas as ocorrências
sed 's/antigo/novo/gi' arquivo.txt       # case-insensitive, global
sed 's/antigo/novo/2' arquivo.txt        # substituir apenas a 2ª ocorrência

# Edição in-place
sed -i 's/localhost/192.168.1.100/g' config.conf      # editar o arquivo diretamente
sed -i.bak 's/antigo/novo/g' arquivo.txt              # com backup (.bak)
sed -i'' 's/DEBUG/INFO/g' app.properties              # sem extensão de backup

# Deleção de linhas
sed '/^#/d' arquivo.conf                 # deletar linhas que começam com #
sed '/^$/d' arquivo.txt                  # deletar linhas vazias
sed '5d' arquivo.txt                     # deletar linha 5
sed '5,10d' arquivo.txt                  # deletar linhas 5 a 10
sed '/inicio/,/fim/d' arquivo.txt       # deletar do padrão inicio ao fim

# Inserção e adição
sed '3i\nova linha' arquivo.txt         # inserir linha ANTES da linha 3
sed '3a\nova linha' arquivo.txt         # inserir linha APÓS a linha 3
sed '/padrão/a\texto novo' arquivo.txt  # inserir após linha com padrão

# Range de linhas
sed -n '10,20p' arquivo.txt             # imprimir apenas linhas 10-20
sed -n '/início/,/fim/p' arquivo.txt    # imprimir entre padrões
sed '1~2d' arquivo.txt                  # deletar linhas ímpares (1, 3, 5...)
sed -n '1~2p' arquivo.txt               # imprimir apenas linhas ímpares

# Múltiplos comandos
sed -e 's/foo/bar/g' -e 's/baz/qux/g' arquivo.txt
sed -f script.sed arquivo.txt           # carregar comandos de arquivo

# Exemplos práticos
# Remover trailing whitespace
sed 's/[[:space:]]*$//' arquivo.txt

# Comentar linhas que contêm um padrão
sed '/DISABLE_ME/s/^/# /' config.conf

# Adicionar linha em branco após cada linha
sed 'G' arquivo.txt

# Numerar linhas
sed = arquivo.txt | sed 'N;s/\n/\t/'

# Remover tags HTML
sed 's/<[^>]*>//g' pagina.html

awk — Processamento de campos

# Sintaxe: awk 'padrão { ação }' arquivo
# Variáveis automáticas: $0=linha, $1..$N=campos, NF=nº campos, NR=nº linha

# Básico — campos
awk '{print $1}' arquivo.txt            # imprimir primeiro campo
awk '{print $1, $3}' arquivo.txt        # campos 1 e 3
awk '{print NR, $0}' arquivo.txt        # numerar linhas
awk '{print NF}' arquivo.txt            # contar campos por linha
awk '{print $NF}' arquivo.txt           # último campo

# Delimitador customizado
awk -F: '{print $1, $3}' /etc/passwd    # usuário e UID
awk -F, '{print $2}' dados.csv          # coluna 2 do CSV
awk -F'\t' '{print $1}' tabela.tsv     # tab como delimitador

# Condições
awk '$3 > 1000' /etc/passwd             # linhas onde campo 3 > 1000
awk '/root/ {print}' /etc/passwd        # linhas com padrão "root"
awk '$1 ~ /^[0-9]/' arquivo.txt        # campo 1 começa com dígito
awk 'NR > 5 && NR < 10' arquivo.txt   # entre linhas 5 e 10
awk 'NF > 3' arquivo.txt               # linhas com mais de 3 campos

# BEGIN e END
awk 'BEGIN {print "Início"} {print} END {print "Fim"}' arquivo.txt
awk 'BEGIN {FS=":"} {print $1}' /etc/passwd  # definir FS no BEGIN

# Sum e Count
awk '{sum += $1} END {print sum}' numeros.txt                    # somar coluna
awk '{count++} END {print count}' arquivo.txt                    # contar linhas
awk '{sum += $2; count++} END {print sum/count}' dados.txt       # média

# Formatação com printf
awk '{printf "%-20s %5d\n", $1, $2}' dados.txt    # colunas alinhadas
awk '{printf "%s = %.2f\n", $1, $2/100}' dados.txt

# Exemplos práticos
# Listar processos com uso > 10% de CPU
ps aux | awk '$3 > 10 {print $1, $2, $3, $11}'

# Somar uso de memória por usuário
ps aux | awk 'NR>1 {mem[$1]+=$6} END {for (u in mem) printf "%s\t%.0f KB\n", u, mem[u]}'

# Extrair e reformatar /etc/passwd
awk -F: 'BEGIN {printf "%-15s %-5s %s\n","USUARIO","UID","HOME"} {printf "%-15s %-5s %s\n",$1,$3,$6}' /etc/passwd

# Top 10 IPs em access log do nginx/apache
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head 10

# Processar CSV e calcular total
awk -F, 'NR>1 {total += $4} END {printf "Total: R$ %.2f\n", total}' vendas.csv

# Imprimir linhas entre dois padrões
awk '/INÍCIO/,/FIM/' arquivo.txt

5. Permissões e Ownership

chmod — Permissões

# Modo simbólico
chmod +x script.sh                       # adicionar execute para todos
chmod u+x script.sh                      # execute apenas para owner
chmod g+w arquivo.txt                    # write para grupo
chmod o-r arquivo.txt                    # remover read de others
chmod a+r arquivo.txt                    # read para todos (all)
chmod u=rwx,g=rx,o=r arquivo            # definir permissões explicitamente
chmod ug+rw,o-rwx arquivo               # combinar modificações

# Modo octal (r=4, w=2, x=1)
chmod 755 script.sh                      # rwxr-xr-x (dono: tudo, grupo/outros: leitura+exec)
chmod 644 arquivo.txt                    # rw-r--r-- (dono: leitura+escrita, outros: leitura)
chmod 600 ~/.ssh/id_rsa                  # rw------- (apenas o dono lê/escreve)
chmod 700 ~/privado/                     # rwx------ (apenas o dono acessa)
chmod 777 /tmp/compartilhado/           # todos: leitura+escrita+execução
chmod 400 chave-secreta.pem             # r-------- (somente leitura para dono)

# Recursivo
chmod -R 755 /var/www/html/             # aplicar recursivamente
chmod -R g+w projeto/                   # adicionar write de grupo recursivamente

# Bits especiais
chmod u+s /usr/bin/programa             # setuid (executa como dono do arquivo)
chmod g+s /var/projetos/                # setgid (novos arquivos herdam o grupo)
chmod +t /tmp                           # sticky bit (apenas dono pode deletar)
chmod 4755 /usr/bin/programa           # setuid em octal (4 + permissões normais)
chmod 2755 /var/projetos/              # setgid em octal (2 + permissões normais)
chmod 1777 /tmp                        # sticky bit em octal (1 + permissões normais)

chown e chgrp

chown usuario arquivo.txt               # mudar dono
chown usuario:grupo arquivo.txt         # mudar dono e grupo
chown :grupo arquivo.txt                # mudar apenas grupo
chown -R www-data:www-data /var/www/   # recursivo
chgrp developers projeto/               # mudar grupo
chgrp -R docker /var/run/docker.sock   # recursivo

ACLs — Access Control Lists

# Verificar se filesystem tem ACL montado (necessário acl na opção de mount)
tune2fs -l /dev/sda1 | grep "Default mount options"

# getfacl — visualizar ACLs
getfacl arquivo.txt                      # mostra ACL completa
getfacl -R pasta/                        # recursivo

# setfacl — definir ACLs
setfacl -m u:joao:rw arquivo.txt        # dar rw para usuário joao
setfacl -m g:dev:rx pasta/              # dar rx para grupo dev
setfacl -m o::- arquivo.txt             # remover permissões de others
setfacl -x u:joao arquivo.txt           # remover ACL do usuário joao
setfacl -b arquivo.txt                  # remover todas as ACLs
setfacl -R -m u:deploy:rwx /var/www/   # recursivo
setfacl -d -m g:dev:rw pasta/          # ACL padrão (herdada por novos arquivos)

# Copiar ACLs de um arquivo para outro
getfacl origem.txt | setfacl --set-file=- destino.txt

umask

umask                                    # ver umask atual (ex: 0022)
umask 027                                # definir umask (grupo: sem write; outros: sem acesso)
# Cálculo: arquivo base=666, dir base=777; umask subtrai as permissões
# umask 022 → arquivos=644, dirs=755
# umask 027 → arquivos=640, dirs=750

# Definir permanentemente no ~/.bashrc
echo "umask 027" >> ~/.bashrc

6. Processos

Visualização de processos

ps aux                                   # todos os processos (BSD style)
ps aux | grep nginx                      # filtrar por nome
ps -ef                                   # todos os processos (UNIX style)
ps -ef --forest                          # mostrar árvore de processos
ps -u www-data                           # processos de um usuário específico
ps -p 1234                               # processo com PID específico
ps -o pid,ppid,cmd,%cpu,%mem            # colunas personalizadas

top                                      # monitor interativo
# Atalhos do top: q=sair, k=kill, r=renice, M=por memória, P=por CPU, 1=CPUs individuais

htop                                     # versão melhorada (se instalado)
# Permite scroll, filtros, mouse

Sinais e kill

kill -l                                  # listar todos os sinais
kill 1234                                # SIGTERM (15) — encerramento gracioso
kill -9 1234                             # SIGKILL — encerramento forçado
kill -SIGTERM 1234                       # usando nome do sinal
kill -HUP 1234                           # SIGHUP — recarregar configuração
kill -STOP 1234                          # suspender processo
kill -CONT 1234                          # retomar processo suspenso

pkill nginx                              # kill por nome
pkill -9 chrome                          # forçado por nome
pkill -u usuario                         # kill todos os processos de um usuário
pkill -f "python script.py"             # kill por linha de comando completa

pgrep nginx                              # encontrar PID por nome
pgrep -u www-data                        # PIDs de um usuário
pgrep -l node                            # PID e nome

Prioridade e background

# nice — executar com prioridade (-20 a 19, maior = menor prioridade)
nice -n 10 ./processamento.sh           # executar com prioridade 10 (baixa)
nice -n -5 ./urgente.sh                 # prioridade negativa (alta, requer root)

renice 15 -p 1234                        # mudar prioridade de processo rodando
renice 10 -u usuario                     # mudar prioridade de todos os proc do user

# Background e foreground
comando &                                # executar em background
jobs                                     # listar jobs em background/stopped
fg %1                                    # trazer job 1 para foreground
bg %2                                    # retomar job 2 em background
CTRL+Z                                   # suspender processo atual
CTRL+C                                   # enviar SIGINT (interromper)

nohup ./script.sh &                      # executar imune a HUP (persiste após logout)
nohup ./script.sh > saida.log 2>&1 &   # com redirecionamento
disown -h %1                             # desassociar job do terminal sem encerrar

screen e tmux básico

# screen
screen                                   # nova sessão
screen -S nome_sessao                   # nova sessão nomeada
screen -ls                               # listar sessões
screen -r nome_sessao                   # reconectar
CTRL+A, D                               # detach da sessão
CTRL+A, C                               # nova janela
CTRL+A, N                               # próxima janela
CTRL+A, K                               # encerrar janela

# tmux
tmux                                     # nova sessão
tmux new -s nome                         # nova sessão nomeada
tmux ls                                  # listar sessões
tmux attach -t nome                      # reconectar
tmux kill-session -t nome               # encerrar sessão
CTRL+B, D                               # detach
CTRL+B, C                               # nova janela
CTRL+B, N                               # próxima janela
CTRL+B, %                               # dividir pane vertical
CTRL+B, "                               # dividir pane horizontal
CTRL+B, setas                           # navegar entre panes

7. Serviços com systemd

Gerenciamento básico

systemctl start nginx                    # iniciar serviço
systemctl stop nginx                     # parar serviço
systemctl restart nginx                  # reiniciar
systemctl reload nginx                   # recarregar configuração (sem reiniciar)
systemctl enable nginx                   # habilitar na inicialização do sistema
systemctl disable nginx                  # desabilitar na inicialização
systemctl enable --now nginx             # habilitar e iniciar imediatamente
systemctl status nginx                   # ver status detalhado
systemctl is-active nginx                # retorna "active" ou "inactive"
systemctl is-enabled nginx               # retorna "enabled" ou "disabled"
systemctl list-units --type=service     # listar todos os services
systemctl list-units --type=service --state=failed  # services com falha
systemctl daemon-reload                  # recarregar arquivos de unit após edição

Criação de unit file

# Criar /etc/systemd/system/meu-app.service
cat > /etc/systemd/system/meu-app.service << 'EOF'
[Unit]
Description=Minha Aplicação
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=appuser
Group=appgroup
WorkingDirectory=/opt/meu-app
ExecStart=/opt/meu-app/bin/start.sh
ExecStop=/opt/meu-app/bin/stop.sh
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
Environment=NODE_ENV=production
EnvironmentFile=/etc/meu-app/env

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now meu-app

journalctl — Logs do systemd

journalctl -u nginx                      # logs do serviço nginx
journalctl -u nginx -f                   # seguir em tempo real
journalctl -u nginx --since "1 hour ago"
journalctl -u nginx --since "2024-01-01" --until "2024-01-02"
journalctl -u nginx -n 100              # últimas 100 linhas
journalctl -u nginx -p err              # apenas erros e superiores
journalctl --disk-usage                  # espaço usado pelo journal
journalctl --vacuum-time=7d             # remover logs com mais de 7 dias
journalctl -b                            # logs desde o último boot
journalctl -b -1                         # logs do penúltimo boot
journalctl -k                            # apenas mensagens do kernel (dmesg)

systemd timers (alternativa ao cron)

# Criar /etc/systemd/system/backup.timer
cat > /etc/systemd/system/backup.timer << 'EOF'
[Unit]
Description=Backup Diário

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
EOF

# Criar o service correspondente: /etc/systemd/system/backup.service
cat > /etc/systemd/system/backup.service << 'EOF'
[Unit]
Description=Script de Backup

[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
EOF

systemctl enable --now backup.timer
systemctl list-timers                    # listar todos os timers

8. Redes

ip — Configuração de rede

ip addr                                  # listar interfaces e IPs (substituto do ifconfig)
ip addr show eth0                        # detalhes de uma interface
ip addr add 192.168.1.100/24 dev eth0  # adicionar IP temporário
ip addr del 192.168.1.100/24 dev eth0  # remover IP

ip link show                             # listar interfaces (estado)
ip link set eth0 up                      # ativar interface
ip link set eth0 down                    # desativar interface

ip route show                            # tabela de roteamento
ip route add default via 192.168.1.1    # adicionar gateway padrão
ip route add 10.0.0.0/8 via 10.10.0.1  # rota estática
ip route del 10.0.0.0/8                 # remover rota

ip neigh show                            # tabela ARP

Diagnóstico de rede

# ss — estatísticas de sockets (substituto moderno do netstat)
ss -tuln                                 # TCP/UDP em LISTEN, numérico
ss -tulnp                                # inclui nome do processo (root)
ss -s                                    # resumo de estatísticas
ss -t state established                 # conexões TCP estabelecidas
ss -tp | grep nginx                      # conexões do nginx

# netstat (legado, pode não estar instalado)
netstat -tuln                            # portas em escuta
netstat -rn                              # tabela de roteamento

# ping e traceroute
ping -c 4 google.com                     # 4 pings
ping -i 0.2 -c 100 192.168.1.1         # ping rápido com intervalo 0.2s
ping -s 1400 192.168.1.1               # testar MTU

traceroute google.com                    # rastrear rota
traceroute -T google.com                 # usando TCP SYN
tracepath google.com                     # alternativa sem root

# curl
curl https://api.exemplo.com             # GET request
curl -s https://api.exemplo.com         # silencioso (sem progress bar)
curl -o arquivo.zip https://url/file    # baixar arquivo
curl -L https://url                      # seguir redirecionamentos
curl -I https://google.com              # apenas headers (HEAD request)
curl -X POST -H "Content-Type: application/json" \
     -d '{"key":"valor"}' https://api.exemplo.com
curl -u usuario:senha https://api.com   # autenticação básica
curl -k https://self-signed.exemplo.com # ignorar erro de certificado
curl --connect-timeout 5 https://api.com  # timeout de conexão

# wget
wget https://url/arquivo.tar.gz         # baixar arquivo
wget -O nome.tar.gz https://url/arq    # salvar com nome específico
wget -q --show-progress https://url/f  # progresso sem verbose
wget -c https://url/arquivo             # retomar download interrompido
wget --limit-rate=1m https://url       # limitar velocidade

# nmap (scanner de portas)
nmap 192.168.1.1                         # scan básico
nmap -p 80,443,22 192.168.1.1          # portas específicas
nmap -p 1-1000 192.168.1.1             # range de portas
nmap -sn 192.168.1.0/24                # ping scan (hosts ativos)
nmap -sV 192.168.1.1                    # detectar versões de serviços
nmap -O 192.168.1.1                     # detectar OS (root)

iptables e firewalld

# iptables básico
iptables -L                              # listar regras
iptables -L -n -v                        # detalhado com contadores
iptables -A INPUT -p tcp --dport 80 -j ACCEPT   # permitir porta 80
iptables -A INPUT -p tcp --dport 22 -j ACCEPT   # permitir SSH
iptables -A INPUT -j DROP               # bloquear todo o resto
iptables -D INPUT -p tcp --dport 80 -j ACCEPT   # deletar regra
iptables -F                              # flush (limpar todas as regras)
iptables -P INPUT DROP                  # política padrão DROP

# Salvar e restaurar regras
iptables-save > /etc/iptables/rules.v4
iptables-restore < /etc/iptables/rules.v4

# firewalld (CentOS/RHEL/Fedora)
firewall-cmd --state                     # status
firewall-cmd --list-all                  # listar regras da zona padrão
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --zone=public --remove-port=8080/tcp --permanent
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --reload                    # aplicar mudanças permanentes
firewall-cmd --zone=public --list-ports  # listar portas abertas

DNS

# dig — consulta DNS detalhada
dig google.com                           # consulta A (IPv4)
dig google.com AAAA                      # IPv6
dig google.com MX                        # registros de email
dig google.com NS                        # nameservers
dig @8.8.8.8 google.com                 # usar servidor DNS específico
dig +short google.com                    # apenas o resultado
dig +trace google.com                    # tracear resolução
dig -x 8.8.8.8                           # lookup reverso

# nslookup
nslookup google.com                      # consulta simples
nslookup google.com 8.8.8.8             # usando servidor específico

# Arquivos de configuração DNS
cat /etc/hosts                           # mapeamentos locais estáticos
cat /etc/resolv.conf                     # servidores DNS do sistema
cat /etc/nsswitch.conf                   # ordem de resolução de nomes

9. SSH

Conexão básica

ssh usuario@host                         # conexão básica
ssh -p 2222 usuario@host                 # porta customizada
ssh -i ~/.ssh/chave_privada usuario@host # chave específica
ssh -v usuario@host                      # verbose (debug)
ssh -vvv usuario@host                    # muito verbose
ssh usuario@host 'ls -la /var/www'      # executar comando remoto
ssh -t usuario@host 'sudo htop'         # forçar TTY (necessário para comandos interativos)

Port Forwarding

# Local — acessar serviço remoto localmente
ssh -L 8080:localhost:80 usuario@servidor  # localhost:8080 → servidor:80
ssh -L 5432:db-interno:5432 usuario@jumpserver  # acesso a DB via jump server
ssh -L 8080:192.168.1.100:80 usuario@host  # acesso a terceiro host via túnel

# Remoto — expor serviço local para o servidor
ssh -R 9090:localhost:3000 usuario@servidor  # servidor:9090 → local:3000
ssh -R 0.0.0.0:80:localhost:8080 usuario@servidor  # expor para a rede do servidor

# Dinâmico — proxy SOCKS
ssh -D 1080 usuario@servidor             # criar proxy SOCKS5 na porta 1080
# Configurar navegador para usar proxy SOCKS5 em localhost:1080

# Manter conexão ativa (background)
ssh -fN -L 5432:localhost:5432 usuario@servidor  # -f=background, -N=sem comando

scp e rsync

# scp — cópia via SSH
scp arquivo.txt usuario@host:/destino/   # upload
scp usuario@host:/remoto/arq .           # download
scp -r pasta/ usuario@host:/destino/    # diretório recursivo
scp -P 2222 arquivo.txt usuario@host:/ # porta customizada

# rsync — sincronização eficiente
rsync -av /origem/ /destino/             # sync local verbose
rsync -avz /origem/ usuario@host:/dest/ # sync remoto com compressão
rsync -avz --progress /origem/ /destino/  # com barra de progresso
rsync -av --delete /origem/ /destino/   # deletar arquivos que não existem na origem
rsync -av --exclude='*.log' /origem/ /destino/  # excluir padrões
rsync -avz -e "ssh -p 2222" /src/ user@host:/dst/  # porta customizada
rsync -n -av /origem/ /destino/         # dry-run (simular sem executar)

Configuração SSH (~/.ssh/config)

# ~/.ssh/config — aliases e configurações por host
cat >> ~/.ssh/config << 'EOF'
Host meu-servidor
    HostName 192.168.1.100
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519

Host jump
    HostName jumpserver.empresa.com
    User bastion
    ForwardAgent yes

Host db-prod
    HostName 10.0.0.50
    User postgres
    ProxyJump jump
    LocalForward 5432 localhost:5432

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    ConnectTimeout 10
EOF

# Usar: ssh meu-servidor (em vez de ssh -p 2222 -i ~/.ssh/id_ed25519 deploy@192.168.1.100)

Gerenciamento de chaves

# Gerar chave
ssh-keygen -t ed25519 -C "seu@email.com"          # ED25519 (recomendado)
ssh-keygen -t rsa -b 4096 -C "seu@email.com"      # RSA 4096 bits (legado)
ssh-keygen -t ed25519 -f ~/.ssh/chave-servidor     # nome customizado

# Copiar chave para servidor
ssh-copy-id usuario@host                           # copia ~/.ssh/id_*.pub
ssh-copy-id -i ~/.ssh/outra_chave.pub usuario@host  # chave específica
# Manual: cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys

# ssh-agent — gerenciar chaves em memória
eval $(ssh-agent)                                  # iniciar agent
ssh-add ~/.ssh/id_ed25519                          # adicionar chave
ssh-add -l                                          # listar chaves carregadas
ssh-add -D                                          # remover todas as chaves

10. Compressão e Arquivos

tar — Tape Archive

# Criar arquivos tar
tar -cf arquivo.tar pasta/               # criar tar (sem compressão)
tar -czf arquivo.tar.gz pasta/          # com gzip
tar -cjf arquivo.tar.bz2 pasta/        # com bzip2
tar -cJf arquivo.tar.xz pasta/         # com xz (melhor compressão)
tar -cvzf arquivo.tar.gz pasta/        # verbose

# Extrair
tar -xf arquivo.tar                      # extrair tar
tar -xzf arquivo.tar.gz                 # extrair gzip
tar -xjf arquivo.tar.bz2                # extrair bzip2
tar -xJf arquivo.tar.xz                 # extrair xz
tar -xzf arquivo.tar.gz -C /destino/   # extrair em diretório específico
tar -xzf arquivo.tar.gz arquivo.txt    # extrair arquivo específico

# Listar conteúdo
tar -tzf arquivo.tar.gz                 # listar arquivos
tar -tJf arquivo.tar.xz | head -20     # listar e filtrar

# Adicionar a arquivo existente
tar -rf arquivo.tar novo_arquivo.txt   # adicionar (não funciona com compressão)

# Exemplos práticos
tar -czf backup-$(date +%Y%m%d).tar.gz /etc/nginx/    # backup com data
tar -czf - pasta/ | ssh usuario@host "cat > /backup/pasta.tar.gz"  # backup direto via SSH

zip, gzip e outros

# zip
zip arquivo.zip file1 file2             # comprimir arquivos
zip -r projeto.zip pasta/               # recursivo
zip -e seguro.zip arquivo.txt           # com senha
unzip arquivo.zip                        # extrair
unzip -l arquivo.zip                     # listar conteúdo
unzip -o arquivo.zip -d /destino/       # extrair em diretório, sobrescrever

# gzip (comprime arquivo individual, remove o original)
gzip arquivo.txt                         # cria arquivo.txt.gz, remove .txt
gzip -k arquivo.txt                      # manter arquivo original
gzip -d arquivo.txt.gz                   # descomprimir
gzip -9 arquivo.txt                      # máxima compressão
zcat arquivo.txt.gz                      # ver conteúdo sem descomprimir
zgrep "padrão" arquivo.txt.gz           # grep em arquivo comprimido

# pigz — gzip paralelo (muito mais rápido em múltiplos cores)
pigz arquivo.txt                         # comprimir
pigz -d arquivo.txt.gz                  # descomprimir
tar -cf - pasta/ | pigz > backup.tar.gz  # tar com pigz

# bzip2 e xz
bzip2 arquivo.txt                        # melhor compressão que gzip
bzip2 -d arquivo.txt.bz2               # descomprimir
xz arquivo.txt                           # melhor compressão (mais lento)
xz -d arquivo.txt.xz                    # descomprimir

11. Shell Scripting

Estrutura básica

#!/usr/bin/env bash
# shebang — indica o interpretador
# #!/bin/bash ou #!/usr/bin/env bash (portável)
# #!/bin/sh — POSIX shell (mais limitado)

set -e           # sair se qualquer comando falhar
set -u           # erro em variável não definida
set -o pipefail  # erro em qualquer parte de um pipe
set -x           # debug — exibir cada comando executado

Variáveis e quoting

# Atribuição (sem espaços ao redor do =)
NOME="Rafael"
NUMERO=42
RESULTADO=$(ls -la)                      # command substitution

# Uso de variáveis
echo $NOME                               # forma curta (pode ser ambíguo)
echo "${NOME}"                           # forma recomendada (chaves)
echo "Olá, ${NOME}!"

# Tipos de quoting
echo "aspas duplas — $NOME é expandido"  # interpola variáveis
echo 'aspas simples — $NOME literal'    # sem interpolação
echo `comando`                           # backticks (legado, evitar)
echo $(comando)                          # command substitution (preferível)

# Variáveis especiais
$0    # nome do script
$1 $2 # argumentos posicionais
$@    # todos os argumentos (como lista)
$*    # todos os argumentos (como string)
$#    # número de argumentos
$?    # exit code do último comando
$$    # PID do script atual
$!    # PID do último processo em background

# Manipulação de strings
ARQUIVO="relatorio_2024.txt"
echo ${#ARQUIVO}                         # comprimento: 19
echo ${ARQUIVO%.*}                       # remover sufixo: relatorio_2024
echo ${ARQUIVO##*.}                      # extensão: txt
echo ${ARQUIVO/2024/2025}               # substituir
echo ${ARQUIVO^^}                        # maiúsculas (bash 4+)
echo ${ARQUIVO,,}                        # minúsculas (bash 4+)
echo ${VAR:-"padrão"}                   # usar padrão se não definida
echo ${VAR:="padrão"}                   # atribuir padrão se não definida

# Arrays
FRUTAS=("maçã" "banana" "laranja")
echo ${FRUTAS[0]}                        # primeiro elemento
echo ${FRUTAS[@]}                        # todos os elementos
echo ${#FRUTAS[@]}                       # quantidade de elementos
FRUTAS+=("uva")                          # adicionar elemento
for fruta in "${FRUTAS[@]}"; do echo "$fruta"; done

Condicionais

# if/elif/else
if [ "$VAR" = "valor" ]; then
    echo "igual"
elif [ "$VAR" = "outro" ]; then
    echo "outro"
else
    echo "diferente"
fi

# Operadores de comparação
# Strings: =, !=, <, >, -z (vazia), -n (não vazia)
# Números: -eq, -ne, -lt, -le, -gt, -ge
# Arquivos: -f (existe e é arquivo), -d (é diretório), -r (leitura), -w (escrita), -x (execução), -s (não vazio)

# Sintaxe [[ ]] — mais poderosa (bash específico)
if [[ "$NOME" == "Rafael" ]]; then echo "Oi Rafael!"; fi
if [[ "$ARQUIVO" =~ \.log$ ]]; then echo "é um log"; fi  # regex
if [[ -f "/etc/nginx/nginx.conf" && -r "/etc/nginx/nginx.conf" ]]; then
    echo "nginx.conf existe e é legível"
fi

# case
case "$OPCAO" in
    start)   systemctl start app ;;
    stop)    systemctl stop app ;;
    restart) systemctl restart app ;;
    *)       echo "Uso: $0 {start|stop|restart}" ; exit 1 ;;
esac

Loops

# for
for i in 1 2 3 4 5; do echo "Item: $i"; done
for i in {1..10}; do echo "$i"; done           # range
for i in {0..100..5}; do echo "$i"; done       # step 5
for arquivo in /var/log/*.log; do
    echo "Processando: $arquivo"
    wc -l "$arquivo"
done
for host in $(cat servidores.txt); do
    ssh "$host" 'hostname; uptime'
done

# while
CONTADOR=0
while [ $CONTADOR -lt 10 ]; do
    echo "Contador: $CONTADOR"
    ((CONTADOR++))
done

# Ler arquivo linha por linha
while IFS= read -r linha; do
    echo "Linha: $linha"
done < /etc/hosts

# until — executar enquanto a condição for FALSA
until ping -c1 google.com &>/dev/null; do
    echo "Aguardando conectividade..."
    sleep 5
done
echo "Conectado!"

Funções

# Declaração de função
backup_dir() {
    local ORIGEM="$1"      # variáveis locais com 'local'
    local DESTINO="$2"
    local DATA=$(date +%Y%m%d_%H%M%S)

    if [[ ! -d "$ORIGEM" ]]; then
        echo "Erro: diretório '$ORIGEM' não encontrado" >&2
        return 1             # retornar código de erro
    fi

    tar -czf "${DESTINO}/backup_${DATA}.tar.gz" "$ORIGEM"
    echo "Backup criado em: ${DESTINO}/backup_${DATA}.tar.gz"
    return 0
}

# Chamar função
backup_dir /etc/nginx /backups
backup_dir /var/www /backups || echo "Backup falhou!"

# Função com retorno de valor (via echo ou variável global)
obter_ip() {
    hostname -I | awk '{print $1}'
}
MEU_IP=$(obter_ip)
echo "IP: $MEU_IP"

getopts — Parsing de argumentos

#!/usr/bin/env bash
# Uso: ./script.sh -h host -p 8080 -v

HOST="localhost"
PORT=80
VERBOSE=false

while getopts ":h:p:v" opt; do
    case $opt in
        h) HOST="$OPTARG" ;;
        p) PORT="$OPTARG" ;;
        v) VERBOSE=true ;;
        :) echo "Opção -$OPTARG requer argumento." >&2; exit 1 ;;
        \?) echo "Opção inválida: -$OPTARG" >&2; exit 1 ;;
    esac
done

shift $((OPTIND - 1))    # remover opções processadas de $@

echo "Host: $HOST, Port: $PORT, Verbose: $VERBOSE"
echo "Argumentos restantes: $@"

trap — Tratamento de sinais

# Limpar recursos ao sair
TMPFILE=$(mktemp)
trap "rm -f $TMPFILE; echo 'Limpeza realizada'" EXIT

# Tratar CTRL+C graciosamente
trap "echo 'Interrompido pelo usuário'; exit 1" INT TERM

# Exemplo completo
cleanup() {
    echo "Encerrando..."
    kill $(jobs -p) 2>/dev/null   # encerrar processos em background
    rm -rf /tmp/meu-script-$$     # limpar arquivos temporários
}
trap cleanup EXIT INT TERM

# Desativar trap
trap - EXIT

Exit codes e boas práticas

# Exit codes: 0 = sucesso, 1-255 = erro
# Convenções: 1=erro geral, 2=uso indevido, 126=não executável, 127=não encontrado

comando && echo "sucesso" || echo "falhou"
comando1 && comando2 && comando3    # executar em cadeia (para se um falhar)

# Verificar resultado
if ! comando; then
    echo "Falhou!" >&2
    exit 1
fi

# Funções de log
log_info()  { echo "[INFO]  $(date '+%Y-%m-%d %H:%M:%S') $*"; }
log_error() { echo "[ERROR] $(date '+%Y-%m-%d %H:%M:%S') $*" >&2; }
log_info "Iniciando processamento..."
log_error "Arquivo não encontrado"

12. Usuários e Grupos

Gerenciamento de usuários

# useradd
useradd joao                             # criar usuário (sem home, sem shell)
useradd -m -s /bin/bash -c "João Silva" -G sudo joao  # completo
useradd -r nginx                         # usuário de sistema (sem home, UID baixo)
useradd -u 1500 -g 1000 joao            # UID e GID específicos
useradd -d /opt/deploy -m deploy        # home customizado

# usermod — modificar usuário
usermod -aG docker joao                  # adicionar ao grupo docker (-a = append)
usermod -aG sudo,adm joao               # múltiplos grupos
usermod -s /bin/zsh joao                # mudar shell
usermod -l novo_nome joao               # renomear usuário
usermod -L joao                          # bloquear conta
usermod -U joao                          # desbloquear conta
usermod -e 2024-12-31 joao             # data de expiração

# userdel
userdel joao                             # remover usuário (mantém home)
userdel -r joao                          # remover usuário E home E mailbox

# passwd
passwd joao                              # alterar senha de joao (root)
passwd                                   # alterar própria senha
passwd -l joao                           # bloquear conta
passwd -u joao                           # desbloquear conta
passwd -e joao                           # expirar senha (forçar troca no próximo login)
chage -l joao                            # informações de expiração de senha

Gerenciamento de grupos

groupadd developers                      # criar grupo
groupadd -g 2000 projetos               # com GID específico
groupmod -n dev developers               # renomear grupo
groupdel antigo_grupo                    # remover grupo
gpasswd -a joao developers              # adicionar ao grupo
gpasswd -d joao developers              # remover do grupo
gpasswd -M joao,maria developers        # definir membros do grupo

# Verificar grupos
id joao                                  # UID, GID e grupos do usuário
groups joao                              # grupos do usuário
cat /etc/group | grep docker             # membros do grupo docker
getent group developers                  # informações do grupo

sudo

# Verificar permissões sudo
sudo -l                                  # listar comandos permitidos ao usuário atual
sudo -l -U joao                         # permissões de joao

# Editar sudoers SEMPRE com visudo
sudo visudo                              # editar /etc/sudoers com validação

# Exemplos de entradas no sudoers
# joao ALL=(ALL:ALL) ALL                          # acesso total
# %sudo ALL=(ALL:ALL) ALL                         # grupo sudo: acesso total
# deploy ALL=(ALL) NOPASSWD: /bin/systemctl       # sem senha para systemctl
# maria ALL=(ALL) NOPASSWD: /usr/bin/docker       # sem senha para docker
# %developers ALL=(ALL) /bin/cat /var/log/*.log   # apenas ler logs

# Arquivos em /etc/sudoers.d/ (preferível ao sudoers)
echo "deploy ALL=(ALL) NOPASSWD: /bin/systemctl" > /etc/sudoers.d/deploy
chmod 440 /etc/sudoers.d/deploy

# su — trocar usuário
su - joao                                # trocar para joao (shell de login)
su -c "comando" joao                     # executar comando como joao
sudo -u joao comando                     # executar como joao via sudo
sudo -i                                  # shell interativo de root

Informações de sessão

who                                      # usuários logados
who -b                                   # data do último boot
w                                        # usuários logados + o que estão fazendo
last                                     # histórico de logins
last joao                                # logins do usuário joao
last reboot                              # histórico de boots
lastfail                                 # tentativas de login falhas (lastb em alguns sistemas)
lastlog                                  # último login de cada usuário

13. Monitoramento e Logs

CPU, memória e I/O

# top interativo
top
# Atalhos: 1=CPUs separadas, M=por memória, P=por CPU, k=kill, q=sair

# htop — versão melhorada
htop
htop -u usuario                          # filtrar por usuário
htop -p 1234,5678                        # PIDs específicos

# btop — versão moderna com gráficos (se instalado)
btop

# iostat — estatísticas de I/O de disco
iostat 1                                 # atualizar a cada segundo
iostat -x 1                              # estendido (await, util%)
iostat -d /dev/sda 1                    # disco específico

# vmstat — memória virtual
vmstat 1                                 # atualizar a cada segundo
vmstat -s                                # resumo de memória
vmstat -d                                # estatísticas de disco

# free — uso de memória
free -h                                  # legível (MB/GB)
free -s 2                                # atualizar a cada 2 segundos
watch -n 1 free -h                       # watch para atualização contínua

# sar — histórico de performance (requer sysstat)
sar -u 1 5                               # CPU: 5 amostras com intervalo 1s
sar -r 1 5                               # memória
sar -d 1 5                               # discos
sar -n DEV 1 5                           # rede

# lsof — arquivos abertos
lsof -i :80                              # quem usa a porta 80
lsof -u joao                             # arquivos abertos pelo usuário
lsof /var/log/app.log                   # quem tem o arquivo aberto
lsof +D /var/www/                       # todos abertos no diretório

Logs do sistema

# dmesg — mensagens do kernel
dmesg                                    # todos os logs do kernel
dmesg | tail -30                         # últimos 30
dmesg -T                                 # com timestamps legíveis
dmesg | grep -i error                    # filtrar erros
dmesg --follow                           # seguir em tempo real
dmesg --level err,warn                  # apenas erros e avisos

# Arquivos de log comuns
/var/log/syslog          # log geral do sistema (Debian/Ubuntu)
/var/log/messages        # log geral (CentOS/RHEL)
/var/log/auth.log        # autenticações (Debian/Ubuntu)
/var/log/secure          # autenticações (CentOS/RHEL)
/var/log/kern.log        # mensagens do kernel
/var/log/nginx/          # logs do nginx
/var/log/apache2/        # logs do Apache
/var/log/mysql/          # logs do MySQL

# Comandos úteis para logs
tail -f /var/log/nginx/error.log         # seguir em tempo real
grep "ERROR" /var/log/app.log | wc -l   # contar erros
grep -i "failed" /var/log/auth.log      # falhas de autenticação
zcat /var/log/syslog.*.gz | grep erro   # buscar em logs comprimidos

# logrotate
logrotate -d /etc/logrotate.conf        # dry run (debug)
logrotate -f /etc/logrotate.d/nginx     # forçar rotação
cat /etc/logrotate.d/nginx               # ver configuração

# Configuração logrotate exemplo
cat > /etc/logrotate.d/meu-app << 'EOF'
/var/log/meu-app/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data adm
    postrotate
        systemctl reload meu-app
    endscript
}
EOF

14. Cron

crontab — Agendamento de tarefas

crontab -l                               # listar crontab do usuário atual
crontab -e                               # editar crontab
crontab -r                               # remover crontab (cuidado!)
crontab -l -u joao                      # listar crontab de outro usuário (root)
crontab -u joao -e                      # editar crontab de outro usuário

# Formato: minuto hora dia-do-mês mês dia-da-semana comando
# *  *  *  *  *  comando
# │  │  │  │  └── Dia da semana (0-7, 0 e 7 = domingo)
# │  │  │  └───── Mês (1-12)
# │  │  └──────── Dia do mês (1-31)
# │  └─────────── Hora (0-23)
# └────────────── Minuto (0-59)

# Exemplos práticos
0 2 * * *     /scripts/backup.sh               # todo dia às 02:00
*/15 * * * *  /scripts/monitorar.sh            # a cada 15 minutos
0 9 * * 1-5  /scripts/relatorio.sh            # 09:00 nos dias úteis (seg-sex)
30 8 1 * *   /scripts/relatorio-mensal.sh     # dia 1 de cada mês às 08:30
0 */4 * * *  /scripts/sync.sh                  # a cada 4 horas
0 0 * * 0    /scripts/manutencao.sh           # domingos à meia-noite
59 23 31 12 * /scripts/fim-de-ano.sh          # 23:59 do dia 31/12

# Atalhos especiais
@reboot  /scripts/inicializacao.sh    # na inicialização do sistema
@hourly  /scripts/por-hora.sh         # equivalente a: 0 * * * *
@daily   /scripts/diario.sh           # equivalente a: 0 0 * * *
@weekly  /scripts/semanal.sh          # equivalente a: 0 0 * * 0
@monthly /scripts/mensal.sh           # equivalente a: 0 0 1 * *
@yearly  /scripts/anual.sh            # equivalente a: 0 0 1 1 *

# Redirecionar saída para evitar emails
0 2 * * * /scripts/backup.sh >> /var/log/backup.log 2>&1
0 2 * * * /scripts/backup.sh > /dev/null 2>&1         # silencioso

# Variáveis de ambiente no crontab
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=admin@empresa.com     # enviar output por email

Arquivos de cron do sistema

# Diretórios de cron do sistema (sem formato de tempo, executados pelo run-parts)
/etc/cron.hourly/   # executado a cada hora
/etc/cron.daily/    # executado diariamente
/etc/cron.weekly/   # executado semanalmente
/etc/cron.monthly/  # executado mensalmente
/etc/cron.d/        # crontabs personalizados (com formato completo)

# Adicionar script ao cron diário
cp meu_script.sh /etc/cron.daily/
chmod +x /etc/cron.daily/meu_script.sh

# anacron — garantir execução mesmo se o sistema ficou offline
cat /etc/anacrontab                      # ver configuração
# período  delay(min)  job-id  comando
# 1        5           cron.daily  run-parts /etc/cron.daily

# Verificar logs do cron
grep CRON /var/log/syslog | tail -20    # Debian/Ubuntu
grep crond /var/log/cron | tail -20     # CentOS/RHEL
journalctl -u cron -f                   # systemd

15. Variáveis de Ambiente e Shell

Variáveis e PATH

# Visualizar variáveis
env                                      # todas as variáveis de ambiente
printenv                                 # idêntico ao env
printenv PATH                            # variável específica
echo $HOME                               # expansão de variável

# Definir variáveis
VAR="valor"                              # variável local (somente no shell atual)
export VAR="valor"                       # exportar (disponível para processos filhos)
export PATH="$PATH:/opt/meu-app/bin"    # adicionar ao PATH
export -f minha_funcao                  # exportar função

# Remover variáveis
unset VAR                                # remover variável
unset -f minha_funcao                   # remover função exportada

# Variáveis importantes
echo $HOME       # diretório home do usuário
echo $USER       # nome do usuário atual
echo $SHELL      # shell padrão
echo $PATH       # caminhos de busca de executáveis
echo $EDITOR     # editor padrão
echo $LANG       # idioma/locale
echo $PWD        # diretório atual
echo $OLDPWD     # diretório anterior
echo $HOSTNAME   # nome do host
echo $TERM       # tipo de terminal

Arquivos de configuração

# Bash
~/.bashrc           # configuração de shell interativo não-login (Ubuntu)
~/.bash_profile     # shell de login (macOS e outros)
~/.profile          # POSIX, carregado por muitos shells de login

# Zsh
~/.zshrc            # configuração do zsh

# Configurações globais
/etc/profile        # carregado por todos os shells de login
/etc/profile.d/     # scripts individuais carregados pelo /etc/profile
/etc/environment    # variáveis de ambiente (sem scripts, formato KEY=VALUE)
/etc/bash.bashrc    # bashrc global (Debian/Ubuntu)

# Recarregar configurações
source ~/.bashrc                         # recarregar sem reiniciar o shell
. ~/.bashrc                              # equivalente (forma POSIX)

# Exemplos de ~/.bashrc
alias ll='ls -alFh'
alias la='ls -la'
alias ..='cd ..'
alias grep='grep --color=auto'
alias k='kubectl'
alias dc='docker-compose'

export EDITOR=vim
export VISUAL=vim
export HISTSIZE=10000
export HISTFILESIZE=20000
export HISTCONTROL=ignoredups:erasedups  # não salvar duplicatas
export HISTTIMEFORMAT="%F %T "          # adicionar timestamp ao history

# Adicionar ao PATH
export PATH="$HOME/.local/bin:$PATH"
export PATH="/opt/go/bin:$PATH"

Alias

alias                                    # listar todos os aliases
alias ll='ls -alFh'                     # criar alias
alias gs='git status'
alias gd='git diff'
alias gl='git log --oneline --graph'
alias dc='docker compose'
alias k='kubectl'
alias tf='terraform'

unalias ll                               # remover alias

# Alias com função para lógica mais complexa
mkcd() { mkdir -p "$1" && cd "$1"; }     # criar diretório e entrar nele
up() { cd $(printf '%*s' $1 | tr ' ' '/'); }  # subir N diretórios

16. Tips e Tricks

history — Histórico de comandos

history                                  # mostrar histórico completo
history 30                               # últimos 30 comandos
history | grep docker                    # buscar no histórico
!!                                       # repetir último comando
!!:s/errado/correto/                    # repetir com substituição
!$                                       # último argumento do comando anterior
!^                                       # primeiro argumento do último comando
!n                                       # executar comando de número n no histórico
!sudo                                    # executar o último comando que começa com sudo
sudo !!                                  # repetir último comando como root

# CTRL+R — busca interativa no histórico
# Digite parte do comando → CTRL+R novamente para continuar buscando
# Enter para executar, → para editar antes de executar, CTRL+G para cancelar

# Configurações úteis do history
export HISTSIZE=50000
export HISTFILESIZE=100000
export HISTCONTROL=ignoreboth:erasedups  # ignorar duplicatas e linhas com espaço
export HISTTIMEFORMAT='%F %T '
shopt -s histappend                      # append em vez de sobrescrever

Redirecionamento

# stdout e stderr
comando > saida.txt                      # redirecionar stdout (sobrescrever)
comando >> saida.txt                     # redirecionar stdout (append)
comando 2> erros.txt                     # redirecionar stderr
comando 2>> erros.txt                    # stderr em append
comando > saida.txt 2>&1                # stdout e stderr para o mesmo arquivo
comando &> saida.txt                     # atalho para stdout+stderr
comando > /dev/null 2>&1                # descartar tudo
comando 2> /dev/null                     # descartar apenas stderr

# stdin
comando < entrada.txt                    # ler stdin de arquivo
comando << EOF                           # heredoc — stdin inline
linha 1
linha 2
EOF
comando <<< "string"                     # herestring — string como stdin

# Pipes e combinações
cmd1 | cmd2 | cmd3                       # encadear comandos
cmd1 |& cmd2                             # pipe incluindo stderr (bash 4+)

# Exemplos práticos de pipes complexos
# Top 10 arquivos maiores no sistema
find / -xdev -type f -printf '%s %p\n' 2>/dev/null | sort -rn | head 10

# Contar tipos de arquivo por extensão
find . -type f | sed 's/.*\.//' | sort | uniq -c | sort -rn

# Monitorar log e notificar quando aparecer padrão
tail -f /var/log/app.log | grep --line-buffered "ERROR" | while read linha; do
    echo "ALERTA: $linha" | mail -s "Erro detectado" admin@empresa.com
done

# Processar CSV com headers
head -1 dados.csv          # ver cabeçalho
tail -n +2 dados.csv | awk -F, '{sum += $3} END {print sum}'

Globbing e Brace Expansion

# Globbing
ls *.txt                                 # todos os .txt
ls arquivo?.txt                          # arquivo + 1 caractere + .txt
ls [aeiou]*                              # começa com vogal
ls [!a-z]*                              # não começa com letra minúscula
ls *[0-9].log                           # termina com dígito antes de .log

# Brace expansion
echo {a,b,c}                             # a b c
echo arquivo{1,2,3}.txt                 # arquivo1.txt arquivo2.txt arquivo3.txt
echo {01..10}                            # 01 02 03 ... 10
echo {a..z}                              # a b c ... z
mkdir -p projeto/{src,tests,docs,scripts}  # criar estrutura de diretórios
cp arquivo.conf{,.bak}                   # fazer backup (arquivo.conf.bak)
mv arquivo.conf{.bak,}                   # restaurar backup

# Extglob (habilitar: shopt -s extglob)
shopt -s extglob
ls !(*.log)                              # tudo exceto .log
rm ?(arquivo)*.tmp                       # zero ou uma ocorrência de "arquivo"

Heredoc

# Criar arquivo com conteúdo multi-linha
cat > /etc/nginx/conf.d/app.conf << 'EOF'
server {
    listen 80;
    server_name app.exemplo.com;
    location / {
        proxy_pass http://localhost:3000;
    }
}
EOF

# Com interpolação de variáveis (sem aspas no delimitador)
PORTA=3000
DOMINIO=app.exemplo.com
cat > /tmp/config.conf << EOF
server {
    listen 80;
    server_name ${DOMINIO};
    location / {
        proxy_pass http://localhost:${PORTA};
    }
}
EOF

# Passar para comando
mysql -u root << 'SQL'
CREATE DATABASE IF NOT EXISTS meu_app;
CREATE USER 'app'@'localhost' IDENTIFIED BY 'senha123';
GRANT ALL PRIVILEGES ON meu_app.* TO 'app'@'localhost';
FLUSH PRIVILEGES;
SQL

xargs avançado e process substitution

# xargs avançado
# -I{} — substituição de placeholder
cat urls.txt | xargs -I{} curl -s {} > /dev/null   # testar URLs
find . -name "*.bak" | xargs -I{} mv {} {}.old      # renomear

# -P — paralelismo
find /imagens -name "*.png" | xargs -P8 -I{} convert {} -resize 800x600 {}_thumb.jpg

# -n — limite de argumentos por invocação
echo "a b c d e" | xargs -n2 echo           # echo a b; echo c d; echo e

# Process substitution — usar saída de comando como arquivo
diff <(sort arquivo1.txt) <(sort arquivo2.txt)  # comparar após ordenar
comm <(sort lista1.txt) <(sort lista2.txt)       # elementos comuns/exclusivos
paste <(cut -d: -f1 /etc/passwd) <(cut -d: -f3 /etc/passwd)  # juntar colunas

# Verificar se dois arquivos têm conteúdo igual após processamento
if diff <(sort a.txt) <(sort b.txt) > /dev/null; then
    echo "Idênticos (ordenados)"
fi

# Copiar permissões de um arquivo para outro
chmod --reference=referencia.sh alvo.sh
chown --reference=referencia.txt alvo.txt

Atalhos úteis do terminal

# Movimentação no cursor (readline)
CTRL+A    # início da linha
CTRL+E    # fim da linha
CTRL+W    # deletar palavra anterior
CTRL+K    # deletar do cursor até o fim da linha
CTRL+U    # deletar do cursor até o início da linha
CTRL+Y    # colar (yank) o que foi deletado
ALT+B     # palavra anterior
ALT+F     # próxima palavra
CTRL+L    # limpar tela (equivalente ao clear)

# Processo
CTRL+C    # SIGINT — interromper processo
CTRL+Z    # SIGTSTP — suspender processo (retomar com fg ou bg)
CTRL+D    # EOF — sair do shell ou finalizar input

# Variáveis rápidas em comandos
mkdir /tmp/novo && cd $_              # $_ = último argumento do comando anterior
ls /var/log && echo "Diretório: $_"   # último argumento = /var/log

Snippets práticos de uso recorrente

# Aguardar processo terminar
while kill -0 $PID 2>/dev/null; do sleep 1; done
echo "Processo $PID terminou"

# Verificar se está rodando como root
if [[ $EUID -ne 0 ]]; then
    echo "Execute como root!" >&2
    exit 1
fi

# Verificar dependências antes de executar
for cmd in curl jq git docker; do
    if ! command -v "$cmd" &>/dev/null; then
        echo "Erro: '$cmd' não encontrado. Instale antes de continuar." >&2
        exit 1
    fi
done

# Mutex — garantir que apenas uma instância do script rode
LOCKFILE="/tmp/$(basename "$0").lock"
if ! mkdir "$LOCKFILE" 2>/dev/null; then
    echo "Script já em execução (lock: $LOCKFILE)" >&2
    exit 1
fi
trap "rmdir '$LOCKFILE'" EXIT

# Spinner para operações longas
spinner() {
    local pid=$1
    local delay=0.1
    local spinstr='|/-\'
    while kill -0 "$pid" 2>/dev/null; do
        local temp=${spinstr#?}
        printf " [%c] " "$spinstr"
        spinstr=$temp${spinstr%"$temp"}
        sleep $delay
        printf "\b\b\b\b\b"
    done
    printf "    \b\b\b\b"
}
operacao_lenta & spinner $!

# Verificar conectividade antes de prosseguir
check_connectivity() {
    if ! ping -c1 -W2 8.8.8.8 &>/dev/null; then
        echo "Sem conectividade com a internet" >&2
        return 1
    fi
}

# Converter tamanhos de forma legível
bytes_para_humano() {
    local bytes=$1
    awk -v b="$bytes" 'BEGIN {
        split("B KB MB GB TB", u)
        for (i=5; i>=1; i--) if (b >= 2^(10*(i-1))) {
            printf "%.2f %s\n", b/2^(10*(i-1)), u[i]; break
        }
    }'
}
bytes_para_humano 1073741824                 # 1.00 GB

# Benchmark simples
time comando
time (for i in {1..100}; do curl -s https://api.exemplo.com > /dev/null; done)

# Testar se porta está aberta
if nc -zw3 192.168.1.100 5432 2>/dev/null; then
    echo "Porta 5432 aberta"
else
    echo "Porta 5432 fechada"
fi

# Executar comando N vezes e medir tempo médio
for i in {1..5}; do time meu-comando; done 2>&1 | grep real | awk '{sum+=$2} END {print "Média:", sum/NR}'