리눅스 '스크립트'명령의 출력을 정리하는 방법


35

linux 'script'명령 http://www.linuxcommand.org/man_pages/script1.html 을 사용하여 일부 대화식 세션을 추적하고 있습니다. 이의 출력 파일에는 백 스페이스 키 입력을 포함하여 인쇄 할 수없는 문자가 포함되어 있습니다.

이러한 출력 파일을 정리하여 화면에 표시된 것만 포함 할 수있는 방법이 있습니까?

아니면 대화식 쉘 세션 (입력 및 출력)을 기록하는 다른 방법이 있습니까?


"또는 대화식 쉘 세션 (입력 및 출력)을 기록하는 다른 방법이 있습니까?" asciinema.org 를 알고 있습니까 ?
masterxilo

답변:


34

파일을 보려면 출력을 통해 col -bp; 제어 문자를 해석합니다. 원하는 경우 더 적은 양으로 파이프를 연결할 수 있습니다.

col -bp typescript | less -R

일부 시스템 col에서는 파일 이름 인수를 허용하지 않으므로 대신이 구문을 사용하십시오.

col -bp <typescript | less -R

1
내 시스템에서 col파일 이름을 허용하지 않으므로 col -bp < typescript 원하는 것을 수행했습니다.
Andrew

나를 위해 작동하지 않습니다, 일부 출력을 스크램블합니다.
Alex

1
내 시스템 less -R자체는 col -bp처음 부터 파이프보다 더 나은 출력을 제공합니다 .
Brian Hawkins

@BrianHawkins 나는 동의한다. 를 사용 col -bp <typescript | less -R하면 색상 콘솔이 표시되지 않습니다. 를 사용 less -R typescript하면 컬러 콘솔이 표시됩니다!
Trevor Boyd Smith

에서 대화식으로 스크립트를 보려는 경우에만 유용합니다 less.
Trevor Boyd Smith

18
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed

다음은 문자열 입력에 대한 해석입니다 perl.

  • s/pattern//g전체를 대체하는 것을 의미합니다 ( g옵션은 첫 번째 대체를 멈추지 않고 전체를 수행함을 의미합니다) 입력 문자열

정규식 패턴에 대한 해석은 다음과 같습니다.

  • \e 특수한 "탈출"제어 문자 (ASCII 0x1A)와 일치
  • (그리고 )그룹의 시작과 끝
  • |그룹이 N 패턴 중 하나와 일치 할 수 있음을 의미합니다. N 패턴이있는 곳
    • [^\[\]] 또는
    • \[.*?[a-zA-Z] 또는
    • \].*?\a
  • [^\[\]] 방법
    • 없는 문자는 NOT 문자 집합을 일치 [하고]
  • \[.*?[a-zA-Z] 방법
    • 문자열로 시작한 [다음 .*?첫 번째 알파 문자까지 욕심이 없습니다.
  • \].*?\a 방법
    • "경고 (종) 문자"라는 특수 제어 문자를 칠 때까지 시작하여 ]욕심이없는 문자열을 찾습니다..*?

1
난 여전히 어떻게 알아낼 필요가 있지만 이것은 실제로 작동합니다;)
asdmin

@asdmin-기본적으로 이것은 출력에서 특정 제어 문자를 제거 typescript하는 perl프로그램에 출력을 에코 한 다음 출력을 unix col명령으로 파이프합니다.이 명령 -b은 스크립트에서 "삭제"키 아티팩트를 제거합니다. 그런 다음 출력을 텍스트 파일로 파이프합니다.
피터 노어

이것은 나를 위해 타이프 스크립트의 첫 번째 줄에서 출력을 스크램블하지만 가장 좋은 대답입니다.
Alex

이것은 일부 타이프 스크립트에서 잘 작동하는 것 같습니다. 허용 된 답변으로 생성 된 출력보다 확실히 더 읽기 쉽습니다.
fakedad

전설적인 답변!
zack

2

많은 양의 script출력을 얻으 려면 perl 스크립트를 반복적으로 해킹합니다. 그렇지 않으면 좋은 편집기로 직접 편집하십시오.

script특정 중요한 순간 ​​(예 : 호스트가 사용자 입력의 첫 번째 문자를 기다리는 경우)에 화면에 표시된 내용을 재현하는 방식으로 출력에서 제어 문자를 제거하는 기존의 자동화 된 방법은 없을 것입니다 .

예를 들어 화면을 비워 두었다가 백 스페이스를 12 번 (필요한 것보다 많이) Andrew $입력 rm /*하고 누른 경우 화면 끝에 표시되는 내용은 실행중인 쉘, 현재 stty설정 에 따라 다릅니다 ( 세션 도중에 변경 될 수 있음) 및 다른 요인도있을 수 있습니다.

위의 내용은 입력 및 출력을 지속적으로 캡처하는 자동화 된 방법에 적용됩니다. 주요 대안은 "스크린 샷"을 찍거나 세션 중에 적절한 시간에 화면을 잘라내어 붙여 넣는 것입니다 (이것은 사용자 안내서, 요일 로그 메모 등).



2

cat filename제어 문자를 제거하는 데 사용했습니다 :-)


imo 이것은 실제로 모든 제어 문자를 제거하기 때문에 더 좋은 대답 입니다.
Nathanael Farley

OSX에서 cat은 색상 제어 문자를 제거하지 않습니다 ...
Nick

9
실제로 cat은 제어 문자를 전혀 제거하지 않으며, 그대로 문자를 출력 한 후 터미널에서 해석합니다. 타이프 스크립트가 터미널 버퍼에 비해 짧고 터미널에서 복사하여 붙여 넣을 수 있으면 효과가 있습니다. 타이프 스크립트가 크면 좋지 않습니다.
mc0e

1
동의했다. 이것은 아무것도 제거하지 않습니다. 그것은 단지 쉘이 그것들을 해석하도록 허용합니다. 그들은 여전히 ​​존재합니다.
Kentgrav

2

경우 당신이 뒤에있어하는 것은 (나중에 bash는 스크립트로를 설정하는 예) 당신의 명령을 기록하는 것입니다, 다음 합리적인 해킹 실행하는 것입니다 script(1)그것을 실행 안에 다음,

bash -x

그 후 grep출력 파일 (일반적으로 "typescript")은 "+"로 시작하는 행을 찾습니다. 정규 표현식 ^\+이 트릭을 수행합니다.


2

출력을 파일에 쓰려면 :

col -bp < typescript >>newfile

원하는 경우 unix2dos 명령을 사용하여 파일을 Windows 형식으로 변환


1
우분투 14.04에서는 줄의 시작과 끝에서 많은 쓰레기가 남습니다. 읽기 쉽지만 실제로는 깨끗하지 않습니다.
mc0e

2

col -bp는 백 스페이스를 원하는대로 처리합니다 (AFAIK). 그러나 색상 이스케이프 시퀀스를 엉망으로 만듭니다. 색상 순서를 먼저 제거한 다음 가능하면 백 스페이스를 처리하는 것이 좋습니다.

이것은 매우 일반적인 요구이며 이에 대한 해결책이 더 이상 없다는 사실에 놀랐습니다. 세션을 스크립팅하는 것이 매우 일반적이며, 누군가는 절차를 검토해야합니다. 작은 타이핑 실수와 색상 이스케이프 시퀀스를 모두 제거하여 나중에 참조 할 수 있도록 "깨끗한"절차 스크립트를 작성하려고합니다. 간단한 ASCII 텍스트가 선호됩니다. 나는 이것이 "사람이 읽을 수있는"것이 의도 한 것이라고 생각하며, 그것은 매우 합리적인 일입니다.


1

나는 당신이 Perl을 사용할 수있는 환경에 있다면 dewtall 이 유닉스 보드에서 비슷한 질문에 대한 답변이 스크립트 출력에서 ​​제어 문자를 제거하는 데 더 효과적 이라는 것을 알았습니다 .

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;
}

제어 문자를 제거하려면 다음을 수행하십시오.

./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed


0

나는 그것을 할 수있는 좋은 방법을 찾았습니다. 내 시스템에서 긴 출력 라인에 "^ M"(빈 공간 다음에 캐리지 리턴)이 뿌려집니다. "^ M"은 널 문자 "^ @"로 대체 할 수 있으며 파일을 표시 할 때 전혀 표시되지 않습니다.

타이밍도 캡처하므로 파일을 완벽하게 재생하려면 아래 명령을 사용하여 "^ M"을 완전히 제거 할 수 없습니다 (scriptreplay가 바이트 수를 계산하기 때문에).

tr '\r' '\0' | sed 's/ \x0//g'

다음과 같이 스크립트 명령을 실행합니다.

script -t -f session.log 2>timing

그래서 나중에 내가하는 일은 :

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

첫 번째 편집 (재생 전)은 파일의 바이트 수를 유지합니다. 두 번째 편집 (재생 후)은 임의의 위치에서 공백을 제거합니다. (기본적으로 scriptreplay는 "typescript"라는 이름의 입력 파일을 검색하므로 "타이밍"후에는 입력하지 않았습니다.


-1

출력의 dos2unix도 트릭을 수행합니다.


7
작업 수행에 사용하는 방법을 설명해 주시겠습니까?
벤 N

-1

다른 해결책은 strings파일 (또는 표준 입력)에서 인쇄 가능한 문자 만 인쇄하는 것입니다.

strings -n 1 filename

-n 1옵션을 사용하면 시퀀스의 최소 길이가 1로 유지되므로 인쇄 할 수없는 문자로 둘러싸인 단일 인쇄 가능 문자도 유지됩니다.

이 접근법의 한 가지 단점은 strings 은 인쇄 가능한 문자의 연속 문자열 사이에 줄 바꿈 추가 입니다. 예를 들어 내용이있는 파일

Foo<SOMECONTROLCHAR>Bar

(어디에 <SOMECONTROLCHAR> 제어 문자 또는 인쇄 할 수없는 다른 문자가 )는 다음과 같이 반환됩니다.

Foo
Bar

주석에서 제기 된 또 다른 문제는 일부 제어 문자 시퀀스가 ​​인쇄 가능 문자와 인쇄 불가능 문자의 조합으로 구성되어 있으며이 방법은 해당 문자의 일부만 제거한다는 것입니다.

그러나 strings질문에 언급 된 백 스페이스와 같은 제어 문자를 제거하는 것이 좋습니다.


strings인쇄 할 수없는 문자를 모두 제거하지는 않습니다. 일련의 인쇄 가능한 문자를 식별하고 인쇄 합니다 . 그것은 같은 것이 아닙니다.
CVn

@ MichaelKjörling, 기본적 strings으로 최소 길이 4의 시퀀스 만 인쇄 -n 1합니다. 최소 길이를 1로 설정하는 옵션을 추가하여 답을 수정 했습니다.이 점을 지적 해 주셔서 감사합니다.
justfortherec

대답은 여전히 strings인쇄 할 수없는 모든 문자 를 제거 한다는 동일한 주장을 하므로 편집 전과 같은 방식으로 여전히 잘못되었습니다. "일부 색상 코드"(및 일반적으로 제어 코드)는 종종 인쇄 가능한 문자와 인쇄 할 수없는 문자로 구성되기 때문에 분명히 손상되었습니다. 예를 들어, 제어 코드 시퀀스가 될 수있는 텍스트 색상 변경 ESC[01;52m여기서 ESC단일 제어 문자 (바이트 값 27)이다. strings제안한대로 사용 [01;52m하면 출력에 남을 수 있습니다 .
CVn

좋은 지적입니다, @ MichaelKjörling. 특히 색상 코드를 사용한 예는 매우 불행했습니다. 답변을 개선하도록 도와 주셔서 감사합니다. 편집 내용이 우려 사항을 적절하게 해결합니까? strings다른 답변 중 일부와 동일한 작업을 수행하지 않을 수도 있지만 IMHO는 질문에 설명 된 문제를 해결하는 올바른 방법입니다.
justfortherec
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.