Como limpar a saída do comando 'script' do Linux

31

Estou usando o comando 'script' do linux link para acompanhar algumas sessões interativas. Os arquivos de saída que contêm caracteres não imprimíveis, incluindo os pressionamentos de tecla backspace.

Existe uma maneira de arrumar esses arquivos de saída para que eles contenham apenas o que foi exibido na tela?

Ou existe outra maneira de gravar uma sessão de shell interativa (entrada e saída)?

    
por Andrew 24.01.2011 / 01:49

13 respostas

31

Se você quiser visualizar o arquivo, você pode enviar a saída através de col -bp ; isso interpreta os caracteres de controle. Então você pode canalizar menos, se quiser.

col -bp typescript | less -R

Em alguns sistemas col não aceitaria um argumento de nome de arquivo, use esta sintaxe:

col -bp <typescript | less -R
    
por 24.01.2011 / 16:20
16
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed

aqui está alguma interpretação da entrada da string para perl :

  • s/pattern//g significa fazer uma substituição no todo (a sequência% de g significa fazer a coisa toda em vez de parar no primeiro substituto)

aqui estão algumas interpretações do padrão regex:

  • \e corresponde ao caractere de controle "escape" especial (ASCII 0x1A)
  • ( e ) são o começo e o fim de um grupo
  • | significa que o grupo pode corresponder a um dos N padrões. onde os padrões N são
    • [^\[\]] ou
    • \[.*?[a-zA-Z] ou
    • \].*?\a
  • [^\[\]] significa
    • corresponde a um conjunto de NOT characters em que os caracteres não são [ e ]
  • \[.*?[a-zA-Z] significa
    • corresponde a uma sequência que começa com [ e, em seguida, faz uma% não coagida% co_de até o primeiro caractere alfa
  • .*? significa
    • corresponde a uma string que começa com \].*?\a e depois faz um ] não-ganancioso até você atingir o caractere de controle especial chamado "o caractere de alerta (sino)"
por 27.09.2013 / 02:44
2

Eu usei cat filename , o que remove os caracteres de controle: -)

    
por 22.04.2012 / 21:16
2

Para uma grande quantidade de script de saída, eu criava um script em perl de forma iterativa. Caso contrário, edite manualmente com um bom editor.

É improvável que exista um método automatizado existente de remover caracteres de controle de script output de uma maneira que reproduza o que foi exibido na tela em determinados momentos importantes (como quando o host estava esperando por primeiro caractere de alguma entrada do usuário).

Por exemplo, a tela pode ficar em branco, exceto Andrew $ , se você digita rm /* e pressiona backspace doze vezes (muito mais do que o necessário), o que é exibido na tela no final depende do shell estava em execução, quais são as configurações atuais de stty (que você pode alterar no meio de uma sessão) e provavelmente alguns outros fatores também.

O acima aplica-se a qualquer método automatizado de captura contínua de entrada e saída. A principal alternativa é tomar "capturas de tela" ou recortar e colar a tela em momentos apropriados durante a sessão (que é o que eu faço para guias do usuário, anotações para um diário, etc).

    
por 24.01.2011 / 13:17
2

Uma resposta para a segunda parte da minha pergunta é usar o recurso de registro em log na tela do gnu: ^A H de dentro de uma sessão de tela em execução. A documentação está no link

    
por 30.01.2011 / 12:33
2

Se o que você está procurando é gravar seus comandos (por exemplo, transformá-los em um script), então um truque razoável é rodar script(1) , então dentro dele rodar

bash -x

Depois, grep do arquivo de saída (geralmente "datilografado") procurando por linhas que começam com "+". A expressão regular ^\+ fará o truque.

    
por 12.02.2011 / 20:16
2

Se você quiser gravar a saída em um arquivo:

col -bp < typescript >>newfile

use o comando unix2dos para converter o arquivo para o formato do Windows se você quiser

    
por 04.10.2012 / 12:09
2

col -bp processa os backspaces conforme desejado (AFAIK). Mas ele manipula as seqüências de escape de cores. Pode ser bom remover as seqüências de cores primeiro e depois processar os backspaces, se possível.

Esta é uma necessidade muito comum, e estou surpreso que não haja mais soluções para isso. É extremamente comum escrever uma sessão e, em seguida, alguém precisa revisar o procedimento. Você quer cortar todos os pequenos erros de digitação e colorir as seqüências de escape para criar um script "limpo" do procedimento para referência futura. Simples texto ASCII preferido. Eu acho que isso é o que é pretendido por "legível por humanos", e é uma coisa muito razoável de se fazer.

    
por 13.09.2013 / 01:29
1

Eu encontrei a resposta que dewtall forneceu para uma pergunta semelhante no quadro do Unix para ser mais eficaz na remoção controle os caracteres da saída do script se você estiver em um ambiente em que o Perl esteja disponível para você.

roteiro de dewtall:

#!/usr/bin/perl
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       \r | # Remove extra carriage returns also
       (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
       (?:\e\]|\x9d) .*? (?:\e\|[\a\x9c]) | # OSC ... (ST|BEL)
       (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\|\x9c) | # (DCS|PM|APC) ... ST
       \e.|[\x80-\x9f] //xg;
       1 while s/[^\b][\b]//g;  # remove all non-backspace followed by backspace
    print;
}

Para remover os caracteres de controle:

./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed
    
por 23.05.2013 / 15:02
1

link foi escrito para resolver este problema.

Faz 4 anos desde a última atualização / usei, mas não me lembro de fazer qualquer coisa que ainda não funcionasse hoje.

    
por 12.01.2016 / 19:05
0

Eu encontrei uma boa maneira de fazer isso. No meu sistema, longas linhas de saída são polvilhadas com "^ M" (espaço em branco seguido de retorno de carro). O "^ M" pode ser bem substituído pelo caractere nulo "^ @", que não é exibido quando você cria o arquivo.

Eu também capturei o tempo, então, para reproduzir o arquivo perfeitamente, eu não posso simplesmente remover o "^ M" completamente usando os comandos abaixo (porque o scriptreplay conta os bytes):

tr '\r' '
script -t -f session.log 2>timing
' | sed 's/ \x0//g'

Eu corro meu comando de script assim:

cat session.log | tr '\r' '
tr '\r' '
script -t -f session.log 2>timing
' | sed 's/ \x0//g'
' > typescript scriptreplay -t timing | sed 's/ \x0//g'

Então, o que eu faço depois é:

cat session.log | tr '\r' '%pre%' > typescript 
scriptreplay -t timing | sed 's/ \x0//g'

A primeira edição (antes da repetição) retém o número de bytes no arquivo. A segunda edição (após o replay) se livra do espaço em branco em lugares aleatórios. (Note que, por padrão, scriptreplay procura pelo arquivo de entrada chamado "typescript", e é por isso que eu não o forneci após "timing").

    
por 22.06.2018 / 19:48
-1

dos2unix na saída também fará o truque

    
por 05.01.2016 / 23:45
-2

Uma outra solução é usar strings que imprime somente caracteres imprimíveis de um arquivo (ou de um padrão entrada):

strings -n 1 filename

A opção -n 1 define o comprimento mínimo das sequências a serem preservadas para um e, portanto, garante que até mesmo caracteres imprimíveis únicos, rodeados por caracteres não imprimíveis, sejam preservados.

Uma desvantagem possível dessa abordagem é que strings adiciona quebras de linha entre sequências contíguas de caracteres imprimíveis. Por exemplo, um arquivo com conteúdo

Foo<SOMECONTROLCHAR>Bar

(onde <SOMECONTROLCHAR> é o caracter de controle ou qualquer outro caractere não imprimível) será retornado como

Foo
Bar

Outra questão levantada nos comentários é que algumas sequências de caracteres de controle consistem em uma combinação de caracteres imprimíveis e não imprimíveis, e essa abordagem só removeria parte deles.

No entanto, strings faz um bom trabalho ao remover caracteres de controle como o backspace mencionado na pergunta.

    
por 01.04.2016 / 16:33

Tags