Setup de terminal para Ubuntu, versionado. Porte do meu setup de macOS, com as partes que só existiam lá removidas em vez de emuladas.
Testado em Ubuntu 24.04 LTS. Deve funcionar em qualquer derivado Debian com apt.
git clone https://github.com/rapha-rodrigues/linux-config.git ~/projects/linux-config
cd ~/projects/linux-config
./install.shConvivem dois tipos de pasta, e a regra de trabalho muda conforme o tipo:
| Tipo | Fonte da verdade | Pastas | Como alterar |
|---|---|---|---|
| Espelho de configuração | a máquina (~/…) |
zsh/, nano/, starship/, yazi/, lazygit/, ccstatusline/, claude/ |
Edite o arquivo vivo em ~ e rode ./backup.sh, ou edite no repo e rode ./install.sh |
| Sub-projeto (desenvolvido aqui) | o repo | scripts/, claude-plugins/, claude-notify/ |
Edite no repo. Cada um tem README.md, CLAUDE.md e Makefile |
linux-config/
├── install.sh # repo → ~ (9 passos, interativo)
├── backup.sh # ~ → repo (--dry-run disponível)
├── zsh/ # .zshrc · .zprofile · .zshenv
├── nano/nanorc
├── starship/starship.toml
├── yazi/ # theme.toml · package.toml
├── lazygit/config.yml
├── ccstatusline/settings.json
├── claude/
│ ├── settings.template.json # gerado por allowlist; NÃO é o settings.json vivo
│ └── hooks/
│ ├── notify.sh # notify-send + som; o clique traz a janela do terminal (X11)
│ ├── push-on-stop.sh # push no celular (Remote Control) quando você está longe
│ └── turn-state.sh # helper dos dois: fim de turno ou pausa, headless
├── scripts/ # funções zsh, instaladas por symlink
├── claude-plugins/ # marketplace local "personal" (sem plugins hoje)
└── claude-notify/ # instalador de um arquivo só das notificações, para mandar a alguém
./install.sh # passo a passo, perguntando antes de cada coisa
./install.sh --yes # responde sim a tudo (provisionamento)
./backup.sh # captura as configs vivas para o repo
./backup.sh --dry-run # mostra o que mudaria, sem escreverinstall.sh nunca sobrescreve em silêncio: um arquivo que difira do repo vira
<destino>.bak.<timestamp> antes de ser trocado.
| # | Passo | Observação |
|---|---|---|
| 1 | Pacotes do apt | zsh git curl nano jq fzf ripgrep bat eza direnv fd-find unzip fontconfig libnotify-bin xdotool xprintidle sound-theme-freedesktop pipewire-bin xclip |
| 2 | Zsh como shell padrão | chsh, vale no próximo login |
| 3 | Oh My Zsh + zsh-autosuggestions e zsh-syntax-highlighting |
|
| 4 | Configs do zsh e do nano | cria ~/.zshrc.local vazio |
| 5 | Starship | instalador oficial |
| 6 | Nerd Font | baixa DroidSansMono das releases do nerd-fonts |
| 7 | yazi e lazygit | yazi não está no apt; o script explica as opções |
| 8 | Claude Code | hooks de notificação (notify.sh, push-on-stop.sh, turn-state.sh), ccstatusline, settings.json a partir do template |
| 9 | scripts/install.sh |
symlinks das funções zsh |
Este repo é feito para ser público. Três decisões vêm daí:
claude/settings.template.json é gerado, não copiado. O backup.sh lê o
~/.claude/settings.json vivo e mantém só uma allowlist de chaves. O que não está na lista
nunca chega ao repo: autoMode (que descreve repos e fronteiras de produção do trabalho),
hooks de terceiros, plugins que não sejam do marketplace local. O caminho absoluto do
marketplace vira um placeholder, resolvido pelo install.sh na hora de escrever.
~/.claude/CLAUDE.md não é versionado aqui. É perfil pessoal. Se quiser versionar, use um
repo privado.
~/.zshrc.local é o escape. Aliases de máquina, atalhos de SSH, IPs internos, tokens: tudo
isso vai nesse arquivo, que o .zshrc carrega no fim e o repo ignora.
| macOS | Ubuntu | |
|---|---|---|
| Gerenciador de pacotes | Homebrew | apt (+ instaladores oficiais para starship, lazygit, yazi) |
Binário do bat |
bat |
batcat (alias no .zshrc) |
Binário do fd |
fd |
fdfind (symlink criado pelo install.sh) |
| Clipboard | pbcopy |
wl-copy no Wayland, xclip/xsel no X11, detectado em runtime |
| Notificação | OSC 777 no Supacode, osascript fora dele |
notify-send (libnotify-bin) + som freedesktop; o clique traz a janela do terminal via xdotool (só X11) |
| Ociosidade para o push no celular | ioreg (HIDIdleTime) |
xprintidle no X11, IdleMonitor por D-Bus no Wayland (Mutter/Muffin) |
| Fontes | ~/Library/Fonts |
~/.local/share/fonts + fc-cache |
| Sintaxe do nano | /opt/homebrew/share/nano/ |
/usr/share/nano/ |
Tema do bat |
seguia a aparência do sistema | fixo em BAT_THEME, sem equivalente universal |
iterm2, raycast, supacode, config-bkp (BetterTouchTool, PopClip, RewriteBar) e o
window manager OmniWM são macOS-only. O brew-audit, os cards impressos, as configs de
VPN e o ai-profile ficaram de fora por decisão, não por incompatibilidade.
Nota sobre o OmniWM: no repo de origem a pasta se chamava
niri/, mas o conteúdo era config do OmniWM, um app macOS. O niri de verdade, no Linux, é um compositor Wayland com config em KDL (~/.config/niri/config.kdl) — formato sem nenhuma relação. Não há o que portar; se quiser niri aqui, é escrever a config do zero.
scripts/— funções zsh (cs,csg,csview,fe,y, e o fluxo de gitgstart/gship/gdone), instaladas por symlink. Editar no repo já vale na próxima shell.make -C scripts test.claude-plugins/— marketplace localpersonal, hoje sem plugins: o coach de inglês que nasceu aqui comoenglish-coachvirou o projeto cc-esol, com repositório e marketplace próprios (claude plugin marketplace add rapha-rodrigues/cc-esoleclaude plugin install cc-esol@esol; oinstall.shmostra os comandos no passo 9). A pasta fica como esqueleto para o próximo plugin pessoal. Plugin instalado roda do cache: depois de editar, reinstale commake -C claude-plugins reinstall PLUGIN=<nome>e reinicie o Claude Code.claude-notify/— geradist/install-claude-notify.sh, as notificações do Claude Code (desktop com clique que traz a janela, push no celular quando você está longe) num instalador de um arquivo só, para mandar a quem não usa este repo. Embute os hooks declaude/hooks/; obackup.sho regera quando captura hooks novos.make -C claude-notify test. Troubleshooting do push que não chega ao celular no README.
claude/hooks/notify.sh (eventos Notification e Stop) mostra a notificação no desktop com som,
filtrada por tipo; o clique traz a janela do terminal da sessão (anotada a cada prompt digitado, pelo
mesmo hook em UserPromptSubmit e SessionStart). claude/hooks/push-on-stop.sh (evento Stop)
pede ao Claude um PushNotification quando o Remote Control está conectado, você está há 60 s ou
mais sem teclado nem mouse e nenhum push saiu no turno: o Claude Code não manda push de fim de turno
sozinho. No terminal isso aparece numa linha, Stop hook feedback: Phone push (idle N s): ..., não como
erro, e o Claude responde só "Push enviado." ou "Push não enviado.".
claude/hooks/turn-state.sh faz os dois concordarem sobre o que é fim de turno (tarefa de background
rodando ou teammate do Agent Teams trabalhando é pausa; teammate e sessão claude -p não avisam). Limites (Wayland, Flatpak, Remote-SSH) no
README do claude-notify.
| Ferramenta | Como instalar |
|---|---|
| yazi | cargo install --locked yazi-fm yazi-cli, snap install yazi --classic, ou o binário das releases |
| lazygit | o install.sh baixa o binário da última release para ~/.local/bin |
| starship | instalador oficial (curl -sS https://starship.rs/install.sh | sh) |
| Claude Code | veja docs.claude.com/claude-code |
| eza | está no apt a partir do Ubuntu 24.04; em versões antigas use o .deb do projeto |
- Documentação em português (pt-BR). Código e comentários podem misturar. Commits em inglês, no imperativo.
- Scripts bash:
set -euo pipefail, helpersinfo/ok/warncoloridos,bash -nantes de entregar. Semrm -rffora de alvosclean. - Ao adicionar um componente, atualize os dois scripts, a tabela e a árvore deste README.