Saída do Terminal
Formate a saída da CLI voltada para o usuário com barras de progresso, spinners e cores, mantendo o stdout canalizável.
Receita
use indicatif::{ProgressBar, ProgressStyle};
use owo_colors::OwoColorize;
fn run(items: &[String]) -> anyhow::Result<()> {
let bar = ProgressBar::new(items.len() as u64);
bar.set_style(ProgressStyle::with_template(
"{spinner:.green} [{bar:30}] {pos}/{len} {msg}",
)?);
for item in items {
bar.set_message(item.clone());
// work...
bar.inc(1);
}
bar.finish_with_message("done".green().to_string());
Ok(())
}Quando usar isso: Operações em lote de longa duração onde os usuários precisam de feedback sem poluir o stdout legível por máquina.
Exemplo de Trabalho
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use std::time::Duration;
fn main() -> anyhow::Result<()> {
let multi = MultiProgress::new();
let overall = multi.add(ProgressBar::new(3));
overall.set_style(ProgressStyle::with_template(
"[{bar:40.cyan/blue}] {pos}/{len} batches",
)?);
for batch in 0..3 {
let sub = multi.add(ProgressBar::new(50));
sub.set_style(ProgressStyle::default_bar());
for _ in 0..50 {
sub.inc(1);
std::thread::sleep(Duration::from_millis(10));
}
sub.finish_and_clear();
overall.inc(1);
}
overall.finish_with_message("all batches complete");
Ok(())
}O que isso demonstra:
MultiProgressrenderiza barras aninhadas sem saída corrompida- O progresso é gravado em stderr por padrão
- Spinners são adequados para tarefas de duração desconhecida
finish_and_clearremove barras concluídas de forma limpa
Mergulho Profundo
stdout vs stderr
| Stream | Uso para |
|---|---|
| stdout | Dados que os usuários canalizam para outros comandos |
| stderr | Logs, progresso, avisos, erros |
Crates de Cores
| Crate | Notas |
|---|---|
owo-colors | Leve, respeita NO_COLOR |
colored | API simples, amplamente utilizada |
console | Usado internamente pelo indicatif |
Detecção de TTY
use std::io::IsTerminal;
let use_color = std::io::stderr().is_terminal();Desabilita cores e animações de progresso quando a saída não é um terminal.
Armadilhas
- Progresso no stdout - Interrompe
mytool | jq. Correção: Sempre anexe o progresso ao stderr. - Ignorando
NO_COLOR- Interrompe CI e preferência do usuário. Correção: Verifique a variável de ambiente antes de estilizar. - Falhas no spinner Unicode - Alguns terminais renderizam spinners de forma inadequada. Correção: Ofereça o modo
--plain. - Colisão de log + progresso - Logs de rastreamento se intercalam com barras. Correção: Use
indicatif-log-bridgeou suspenda as barras durante o registro. - Terminal travado após pânico - A barra de progresso pode deixar o cursor oculto. Correção: Chame
finish()em um guardião ou implementaçãoDrop.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
eprintln! Simples | Scripts e ferramentas apenas para CI | Tarefas longas interativas |
Assinante tracing | Aplicativos de servidor com logs estruturados | CLIs simples de uso único |
ratatui TUI Completo | Dashboards interativos | Scripts em lote em pipelines |
FAQs
indicatif vs console?
indicatif lida com a renderização de progresso. console fornece controle de terminal de nível inferior. Eles se complementam.
Como adiciono ETA?
Os modelos ProgressStyle suportam {eta} quando o comprimento total é conhecido.
Modo silencioso?
Pule a criação da barra de progresso quando --quiet estiver definido ou o stderr não for um TTY.
Suporte ao terminal do Windows?
O Terminal do Windows moderno funciona bem. Teste no cmd.exe mais antigo se você o suportar.
Modo de saída JSON?
Quando --json está ativo, suprima toda a estilização e progresso. Emita apenas JSON no stdout.
Tabelas no terminal?
Use comfy-table ou tabled para saída de coluna alinhada no stdout.
Spinner para totais desconhecidos?
Use ProgressBar::new_spinner() em vez de uma barra dimensionada.
Barras de progresso concorrentes?
MultiProgress coordena o desenho. Uma barra pai mais filhos por tarefa é o padrão usual.
Níveis de log para stderr?
Mapeie -v / -vv para níveis tracing. Mantenha o progresso separado das linhas de log.
Testando a saída do terminal?
Fatore a renderização em funções e afirme sobre strings em testes unitários. Testes TTY completos raramente valem a pena.
Relacionado
- Noções Básicas de CLI - convenções de stdout/stderr
- TUIs com ratatui - interfaces de tela inteira
- Relatório de Erros - formatação de erros stderr
- Melhores Práticas de CLI - regras de UX
Versões da Pilha: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4 e Polars 0.46+.