
Executei um comando no terminal gnome que imprimiu mais saída no terminal do que eu esperava. Gostaria de ler a saída inteira, mas a rolagem do terminal para antes de chegar ao início.
Entendo que posso alterar as configurações do perfil do terminal para permitir rolagem ilimitada ou canalizar a saída para um arquivo, etc.futurosaída, no entanto.
Como posso ver a saída completa do terminal de um comando que já foi executado?
Editar: Tudo bem, isso não pode ser feito. Obrigado a todos!
Responder1
Minha experiência é que o consenso nos comentários está correto - uma vez que o buffer do terminal é excedido, os dados são perdidos (ou tão bons quanto - podem estar na memória que ainda não foi substituída) - e por causa disso você não é possível aumentar retroativamente o tamanho do buffer.
Esta resposta está no limite entre um comentário, uma resposta e talvez um exagero para a sua situação. É mais uma abordagem sugerida que pode resolver a sua situação - principalmente o problema de não saber que você precisa do log até que seja tarde demais (problemas não causais são difíceis), mas não é uma resposta direta à sua pergunta.
De qualquer forma, foi muito longo para um comentário. Não estou listando explicitamente todo o código necessário para implementar essa abordagem, principalmente porque há diversas decisões de implementação que precisam ser tomadas; se você precisar de informações mais detalhadas, ficarei feliz em fornecê-las.
Script
está longe de ser agradável de lidar
Em primeiro lugar, o script
utilitário foi sugerido como uma solução provisória para evitar a perda de dados sem aumentar o tamanho do buffer (que tem implicações de segurança quando definido como ilimitado). Se alguma vez existiu um utilitário que precisasse de algum TLC, script
é esse. Então, novamente, foi desenvolvido pela equipe do kernel. Leia isso como quiser.
Acho script
que frequentemente é mais problemático do que vale a pena (pós-processamento para torná-lo legível para semi-humanos, etc.) e, em vez disso, comecei a usar um método simplificado para registrar stdout, stdin e/ou stderr. Em certo sentido, isso é uma recriação de script, mas com controle total, em vez de ficar à mercê das script
configurações de log codificadas.
Essa abordagem pode ser integrada de maneira relativamente perfeita em suas sessões de shell e, nos raros casos em que você estourou o buffer do terminal, você terá um arquivo temporário com esse conteúdo. Para manter o registro 'limpo', existem algumas etapas de manutenção que você deverá seguir. Além disso, os mesmos problemas de segurança (log de todas as saídas do terminal) existirão por padrão; no entanto, existe um método simples para criptografar os logs.
Existem 3 etapas básicas:
- Configure o redirecionamento para dividir o stdout (e o stderr, se desejar) em um arquivo e no terminal. Mantive este exemplo simples e não estou direcionando stdin ou stderr para o arquivo - no entanto, se você entender o exemplo de redirecionamento stdout, o resto é trivial.
- Configure .bashrc para que esse log seja iniciado sempre que um shell for aberto.
- Quando um determinado shell está fechando, use o bash integrado
TRAP
para chamar o código do usuário que encerrará o log da sessão (você pode excluir o arquivo, arquivá-lo, etc.)
Com esta abordagem você terá efetivamente uma rede de segurança invisível que permitirá ver todo o histórico de uma determinada sessão do shell (com base no que você redireciona - novamente, para simplificar as coisas, estou mostrando apenas o stdout); quando você não precisa, você nem deveria saber que está lá.
Detalhes
1. Configurar o redirecionamento
O trecho de código a seguir criará um descritor de arquivo 3, que aponta para um arquivo de log. stdout é redirecionado para 3 e, usando tee
, dividimos esse fluxo de volta no terminal (equivalente a stdout). Você pode adicionar stderr trivialmente ao mesmo arquivo de comando/log, canalizá-lo para um arquivo diferente ou deixá-lo como está (não registrado).
logFile=$(mktemp -u)
exec 3>&1 1> >(tee $logFile >&3)
Você descobrirá que esse arquivo de log é muito mais limpo do que aquele gerado pelo script; ele não armazena retrocessos, avanços de linha e outros caracteres especiais que são frequentemente indesejados.
Observe que se você deseja que o logFile seja criptografado, você pode fazer isso facilmente adicionando um estágio de pipe adicional após o comando tee atravésabressl.
2. Automatize a geração de logs
Em .bashrc adicione o mesmo código acima. Cada vez que um novo shell é criado, um arquivo de log específico para aquela sessão será criado.
export logFile=$(mktemp -u)
exec 3>&1 1> >(tee $logFile >&3)
echo "Current session is being logged in $logFile"
3. Fechar automaticamente o log quando o shell estiver fechando
Se você deseja que o arquivo de log seja excluído quando a sessão terminar, você pode usar a trap
função interna do bash para detectar que a sessão está terminando e chamar uma função para endereçar o arquivo de log, por exemplo (também em .bashrc).
trap closeLog EXIT
closeLog () {
rm -f "$logFile" >/dev/null 2>&1
}
A limpeza do log de sessão pode ser realizada de diversas maneiras diferentes. Esta abordagem será chamada quando o shell estiver fechando, capturando o sinal de 'saída'. Neste ponto, você pode excluir o arquivo de log, movê-lo/renomeá-lo ou qualquer outra coisa para limpá-lo. Você também pode limpar os arquivos de log por um cron job em vez de por meio de um TRAP (se essa abordagem for usada, sugiro uma tarefa de limpeza periódica se você ainda não tiver uma configurada para o diretório /tmp; como se o shell bash trava, a armadilha EXIT não será acionada).
Nota sobre como lidar com subshells
Uma situação interessante se desenvolverá com os subshells. Se um novo shell interativo for aberto sobre um já existente, um novo log será criado e tudo deverá funcionar bem. Quando esse shell for encerrado (retornando ao pai), o login nesse arquivo será retomado. Se você quiser resolver isso de forma mais clara - talvez até mantendo um log comum para subshells (interativo ou não), você precisará detectar (em .bashrc) que está em um subshell aninhado e redirecionar para o arquivo de log do pai em vez de criando um novo. Você também precisará verificar se está em um subshell para que sua chamada 'trap' não exclua o arquivo de log do pai ao sair. Você pode obter o nível de shell aninhado na variável ambiental bash SHLVL, que armazena a 'profundidade' de sua pilha de shell.
Nota sobre como manter seu log 'limpo':
Se você redirecionar o stdin para o arquivo de log, você acabará com muitos dos mesmos artefatos indesejados gerados pelo utilitário de script. Isso pode ser resolvido adicionando um estágio de filtro (por exemplo, sed/grep) entre o redirecionamento e o arquivo. Basta criar um regex que remova tudo o que você não deseja registrar. Para limpá-lo completamente, seria necessário um processamento bastante profundo (talvez armazenar em buffer cada nova linha antes de gravar no arquivo, limpá-la e depois gravá-la). Caso contrário, será difícil saber quando um backspace é “lixo” ou intencional.
Responder2
A forma tradicional era usar PuTTY e manter milhares de linhas. Também há tela, já que poucos usuários de Linux (ou locais) usam PuTTY.
Agora que o Windows tem ssh na linha de comando, ele está caindo em desuso.