대화형 명령 문제를 해결하고 싶은데 다음을 수행하고 싶습니다.
- 버퍼링이나 라인 버퍼링 없이 원래 색상으로 화면에 인쇄된 출력물을 봅니다.막힌-buffered,) 명령이 생성하기 때문입니다.
이와 같은 것을 사용하면(이 기본 설정의 일부가 가능하지 않을 수 있음을 인식하여 다음 기본 설정으로 대체합니다.)tee
이 명령의 출력을 파일로 동시에 리디렉션하여 보존할 수 있습니다. 즉, 왜곡되지 않습니다(예: 다음을 전달하여).ANSI 이스케이프 시퀀스올바르게 처리하는 대신 원시 데이터로) - 생성된 로그 파일의 색상입니다.- 또한 다음을 사용하여
tee
이 명령의 출력을 파일로 리디렉션합니다. - 런타임 시 해당 명령의 색상으로 출력 표시
- 생성된 로그를 오염시키지 않습니다.ANSI 이스케이프 시퀀스 - 즉, 터미널에 표시한 후 출력에서 제거하지만앞으로로그 파일에 저장합니다.
일반적으로 tee -a
여기에 로그인하려고 하는 것과 동일한 종류의 명령 출력을 사용하는 것은 나에게 매력적으로 작동하지만일부파이프라인에서 내가 만난 이상한 코너 케이스는 tee
이러한 정상적이고 합리적인 동작을 깨뜨리는 것처럼 보였습니다. 내가 하나 만들었어소량이전에 비슷한 문제를 겪은 사람이 있는지 알아보고 해결책을 제안했지만 제가 찾아낸 관련 자료는 모두 다음과 같습니다.
- 쉘 명령의 출력을 버퍼링되지 않은 상태로 만들려면 어떻게 해야 합니까? - 스택 오버플로
- 티셔츠에 파이핑할 때 색상 보존 — 수퍼유저
- 파이프라인에서 버퍼링 끄기
- 정크 문자가 없는 스크립트 명령
- 스크립트 출력에서 제어 문자(콘솔 코드/색상 포함) 제거
- Unix "script" 명령의 출력 형식: 백스페이스, 개행 및 삭제된 문자를 제거하시겠습니까? - 스택 오버플로
- 대화형 스크립트로 티와 함께 실시간 인쇄문 - Think Tank 101 - CC 저작권 기반 Q&A 공유 플랫폼
그러나 이러한 리소스 중 어느 것도상당히충분한 힌트가 주어지면, 나는 그것을 사용하여 내가 원하는 것에 맞는 것을 거의 내가 원하는 만큼 빨리 엮을 수 있을 것이라고 생각했습니다.좋다 -마침내 도움이 필요한 로그를 생성할 수 있는 사람에게 전달할 수 있습니다.찾다물론 그들도 몇 가지 물건을 가지고 있습니다.
나는 가지고있다시험을 마친내가 읽은 내용에는 unbuffer
- 및 -를 기반으로 한 몇 가지 다양한 조언이 제공되었으며 이 질문을 쓰기 시작하기 전에 몇 가지 제공을 고려하고 있었지만 아직 마지막 조언을 수행하지 못했습니다. 저는 OS X v10.11.6 "El Capitan"을 사용하고 있습니다. 문제를 해결하려는 명령은 다음과 같습니다.script
stdbuf
/usr/bin/bash
HOMEBREW_BUILD_FROM_SOURCE=1 brew upgrade -vd --build-from-source mailutils
brew
홈브루 패키지 관리자소스에서 빌드하고 업그레이드하려고 하는 Mailutils 버전은 v3.3입니다(현재 v3.2를 사용하고 있습니다).깊은완전히 바꾸는 건 의문다른그걸 주문해반품파이프라인의 일부로 사용되면 청크 버퍼링된 출력이 생성됩니다(내가 이해하는 경우).바르게, 할 것이다어느쉘 명령을 실행하면 파이프 자체를 설정하면 블록 버퍼링이 발생할 수 있다고 언급되어 있지만 문제는 해결되지 않습니다. 여기에서 캡처하려는 로그로 원하는 결과를 얻으려면 어떤 도구를 사용할 수 있나요?
답변1
프로세스 대체1 변화시키자script
이것이 타이프스크립트에 나와 있는 내용입니다.
이스케이프 시퀀스가 제거된 로그를 작성하는 대신 임의의 명령을 사용하여 이를 제거하는 스크립트를 실행할 수 있습니다. 비교적 새로운 버전의 macOS나 FreeBSD 이외의 시스템에서는 구현마다 지원하는 옵션이 다르기 때문에 명령이 약간 다릅니다. 자세한 내용은 아래를 참조하세요.script -q >(./dewtell >>outfile) brew args...
script -aq outfile brew args...
./dewtell
script
지금까지의 이야기(대체 솔루션 포함)
귀하의 솔루션
명령 은 스크립트 및 brew
와 같은 여러 가지 다른 출력 생성 프로그램을 하위 프로세스로 실행하며 출력을 로 파이핑하면 출력 (적어도 일부 하위 프로세스의)이 버퍼링되어 터미널에 표시되지 않습니다. 실시간../configure
make
brew
tee
brew args... 2>&1 | tee -a outfile
당신은 알아냈어요script
다음을 실행하여 script -aq
문제를 해결했습니다 .표준 출력터미널 2-k
, 자신의 입력을 녹음하려면 다음을 통해 수행할 수도 있습니다.터미널에 울리지 않고 입력하더라도. 당신은 더 많은 것을 발견합니다두테르테의 확장판~의Gilles의 Perl 스크립트도착하다파일에서 이스케이프 시퀀스 제거생성된 TypeScript를 효율적으로 정리하여 필요한 것으로 변환합니다.
Gilles의 원본 스크립트와 dewtell의 확장 버전 간의 차이점은 둘 다 색상 변경을 지정하는 것을 포함하되 이에 국한되지 않는 이스케이프 시퀀스를 제거하는 반면 dewtell의 스크립트는 캐리지 리턴( 및 의 출력에서 $'\r'
로 표시됨 )도 제거한다는 것입니다. 백스페이스 문자( 및 의 출력에 표시됨 ) 및 삭제된 것으로 보이는 문자(있는 경우)로 표시됩니다.^M
vim
cat -v
$'\b'
^H
vim
cat -v
특정 Perl 구현 관련 문제
스크립트에 "비교적 새로운" Perl 인터프리터가 필요하다고 보고했습니다. 하지만 새로운 기능은 필요하지 않습니다.use
또는 그렇지 않으면 이에 의존하는 것 같고 macOS 10.11.6 El Capitan을 실행하는 내 친구가 시스템 제공 Perl 5.8.12에서 작동한다는 것을 확인했기 때문에 최신 버전이 필요한 이유(또는 경우)를 모르겠습니다. 펄 하나.기대했다최대사람들은 자신이 가지고 있는 Perl을 사용할 수 있습니다.
하지만 대본은실패했다Mac m
OS 의 경우 그러면 이 문제는 . 이로 인해 색상이 지정된 이스케이프 시퀀스 조각이 출력에 남아 있게 됩니다. 이러한 시퀀스는 일치할 수 없고 나중에 대체 시퀀스가 대신 일치되기 때문입니다 . 그리고[@-~]
LC_COLLATE=C
LC_ALL=C
grep
sed
python
ruby
(?:\e\[|\x9b) [ -?]* [@-~]
\e.
perlbrew
, 저는 이 시스템에 Perl 5.27.5, 5.8.9, 심지어 5.6.2도 설치했습니다. 아무도 이 문제를 겪지 않았습니다.
스크립트를 실행하기 위해 다른 곳에 설치된 Perl 인터프리터가 정말로 필요하거나 사용하려는 경우 /usr/bin/perl
다음을 변경할 수 있습니다.해시 스틱맨 위의 줄은 올바른 경로를 가리킵니다. 또는 /usr/bin/env perl
원하는 perl
실행 파일이 경로에 먼저 나타나는지 여부, 즉 perl
입력하고 누르면 실행될지 여부 로 변경될 수 있습니다 Enter. 또는 스크립트의 파일 이름을 첫 번째 인수로 사용할 수 있습니다. 예를 들어 . /usr/local/bin/perl dewtell
대신 인터프리터를 명시적으로 호출합니다 ../dewtell
원본 타이프스크립트를 보존하거나 교체하는 방법
TypeScript에서 이스케이프 시퀀스를 제거해야 하는 일부 사용자는 처리되지 않은 이전 TypeScript를 유지하기를 원합니다. 그러한 사용자가 이름이 지정된 TypeScript를 처리 dirty.log
하고 여기에 출력을 쓰려 는 경우 필요한 경우 실행된 다른 명령을 대체하여 clean.log
실행합니다../dewtell dirty.log > clean.log
./dewtell
두테르테의 대본(또는 사용하려는 다른 스크립트).
TypeScript를 "제자리"로 수정하려면 -i
에 전달하여 perl
실행 하면 됩니다.perl -i.orig dewtell typescript
typescript
는 에서 생성된 타이프 스크립트 script
, .orig
는 백업 파일에 사용되는 접미사, dewtell
은 Perl 스크립트입니다. 또는 백업 접미사가 제공되지 않으므로 원본 파일을 삭제하는 대신 실행할 수도 있습니다. 이러한 방법은 모든 Perl 스크립트에 적용되지는 않지만 입력을 읽고 이 스크립트에 적용됩니다.perl -i dewtell typescript
<>
<>
펄 측에서는-i
.
sponge
원래 타이프스크립트에 변경 사항을 다시 기록 하곤 했습니다 . 이 방법 역시 훌륭하고 신뢰할 수 있는 방법입니다.더 많은 유틸리티설치되어 있습니다.
이스케이프 시퀀스가 기록되지 않도록 방지
남은 질문은 처음에 이스케이프 시퀀스가 제거된 로그를 작성하는 방법입니다. ~처럼당신은 말한다:
[T] 이 모든 것을 단일 파이프로 연결하는 방법도 있을 수 있지만 글을 쓰는 시점에는 다른 의견이나 답변에서 방법을 알 수 없었습니다.
파이프 대신 프로세스 대체를 사용하십시오.
문제는 script
대부분의 (모든?) 시스템에서 이러한 변환을 지원하는 옵션이 없다는 것입니다. script
기록된 파일의 이름은 사용자가 지정한 이름이거나 기본값 typescript
(표준 출력 아님) 이므로 파이핑은 script
TypeScript에 기록되는 내용에 영향을 미치지 않습니다.
script
파이프 연산자( ) 오른쪽에 명령을 배치하여 파이프합니다.|
도착하다이것도 좋은 생각이 아닙니다. 귀하의 경우 이는 특히 brew
표준 출력이 파이프일 때 출력 또는 해당 하위 프로세스가 버퍼링되어 표시해야 할 때 표시되지 않기 때문입니다.
이 문제가 해결되더라도 합리적으로 사용할 수 있는 방법은 없습니다.관로1 이 작업을 함께 script
완료합니다 .
그러나 이는 프로세스 교체를 통해 수행될 수 있습니다.3 인치프로세스 교체1 (또한여기에 설명되어 있습니다), 당신은 또는. 쉘은<(command...)
>(command...)
명명된 파이프표준 출력 또는 입력으로 각각 사용하십시오.서브쉘~에command...
달리기. 텍스트 또는는 명명된 파이프의 파일 이름으로 대체됩니다.<(command...)
>(command...)
치환--따라서 프로그램에 매개변수로 전달하거나 리디렉션 대상으로 사용할 수 있습니다.
- 달리기를 위해
<(command...)
command...
좋다그 출력원하는 파일의 내용입니다다음에서 읽기. 4 - 달리기를 위해
>(command...)
command...
좋다입력원하는 파일의 내용입니다에게 편지를 쓰다. 4
모든 시스템이 명명된 파이프를 지원하는 것은 아니지만 대부분은 지원합니다. 모든 쉘이 프로세스 대체를 지원하는 것은 아니지만 Bash는 이를 지원하며, Bash 버전은 이를 지원할 수 있는 시스템에서 실행되고 POSIX 모드가 쉘에서 꺼져 있는 한 이에 대한 지원을 무시하지 않습니다. 세게 때려대개특히 원격 최신 운영 체제를 사용하는 경우 프로세스 교체에 액세스할 수 있습니다. Mac OS X 10.4.11 Tiger(PPC) 시스템에서도 "$BASH_VERSION"
프로세스 2.05b.0(1)-release
교체가 제대로 작동합니다 .
script
최신 macOS 시스템에서 s 구문을 사용할 때 이를 수행하는 방법은 다음과 같습니다.
이는 macOS 10.11 El Capitan 시스템에서 작동하며 다음을 통해 작동합니다.해당 맨페이지, 모든 macOS 시스템이것은 적어도 macOS 10.9 Mavericks로 돌아갑니다.아마도 이전:
script -q >(./dewtell >>clean.log) brew args...
사용자 입력을 포함하여 터미널에 기록된 모든 내용을 기록합니다.그것이 당신에게 다시 에코되면, 즉 터미널에 나타나는 경우 일반적으로 그렇습니다. 자신의 입력을 기록하고 싶다면나타나지 않더라도, 이는 일반적으로 비밀번호를 입력할 때 발생하므로너의 답-k
, 옵션 추가 :
script -kq >(./dewtell >>clean.log) brew args...
두 경우 모두 ./dewtell
실행하는 명령으로 바꾸십시오.두테르테의 대본또는 출력을 필터링하는 데 사용하려는 다른 프로그램이나 스크립트,clean.log
여기에는 typescript에 기록될 파일 이름(이스케이프 시퀀스 생략)이 포함되어 있고 5에는 실행 중인 명령과 해당 인수가 포함되어 있습니다.brew args...
로그에 덮어쓰기 또는 추가
재정의하고 싶다면clean.log
파일에 추가한 다음 .을 사용하는 대신 프로세스 대체를 통해 실행되는 명령에 의해 실제 파일이 기록되므로 .>clean.log
>>clean.log
>
>>
>(
)
>>(
not 을 사용하려고 하지 마십시오 >(
. 구문 오류이며 프로세스 대체가 리디렉션을 의미하지 않기 때문에 의미가 >
없습니다 >(
.
이 경우 로그 파일을 덮어쓰는 것을 방지하려면 -a
로 전달하지 마십시오 . 이 파일은 그냥 열리게 됩니다.script
명명된 파이프추가 모드 - 일반 쓰기를 위해 여는 것과 동일한 효과가 있습니다. 그런 다음 덮어쓰거나 추가합니다.clean.log
, 여전히 서브 쉘에서 또는 가 사용되는지 여부에 따라 다릅니다.>clean.log
>>clean.log
마찬가지로 내부적으로(또는 어디에서나) >&
or 를 사용하거나 추가하지 마세요 &>
. 오류나 경고가 생성되면 작성하기보다는 확인하고 싶을 것이기 때문입니다.2>&1
>(
)
./dewtell
clean.log
. 이 script
명령은 TypeScript에 표준 오류의 텍스트를 자동으로 포함합니다. 이를 위해 특별한 작업을 수행할 필요가 없습니다.
다른 운영 체제에서
~처럼너의 답설명하다:
[S]
script
이 명령의 일부 버전은 구문이 다릅니다. 제공된 버전은 OS X/macOS용이므로 필요에 따라 조정하세요.
GNU/리눅스
대부분의 GNU/Linux 시스템은 script
다음에서 제공하는 구현을 사용합니다.유틸리티Linux. 쉘을 시작하는 대신 특정 명령을 실행하려면 해당 -c
옵션을 사용하고 전체 명령을 다음과 같이 전달해야 합니다.단일 명령줄 매개변수to 로 script
묶으면 이를 따옴표로 묶어서 수행할 수 있습니다. 이는 와 같은 최신 macOS 시스템의 버전과 다릅니다 script
. 이 버전에서는 출력 파일 이름 뒤에 배치된 여러 인수로 명령을 자연스럽게 전달할 수 있습니다( 와 같은 옵션 없이 -c
).
그래서Debian, Ubuntu, Fedora, CentOS 및 대부분의 기타 GNU/Linux 시스템, 다음 명령을 사용할 수 있습니다( brew
명령 6 이 있는 경우 또는 이를 실행하고 변환된 출력을 기록하려는 명령으로 바꾸십시오).
script >(./dewtell >>clean.log) -qc 'brew args...'
script
시스템에서 와 마찬가지로 GNU/Linux에서 로깅 시작 및 종료 방법에 대한 추가 메시지를 포함 -q
하려면 제거하십시오. script
이 옵션을 사용하더라도 -q
이 버전에는 script
실행이 시작된 시점을 나타내는 줄이 상단에 포함되어 있지만 표시되지는 않습니다.너그 줄은 언제 쓰여졌는지에 대한 정보를 쓰거나 표시하지 않습니다.중지됨달리기.
선택의 여지가 없다 -k
. 터미널에 나타나는 텍스트만 기록됩니다. 7
FreeBSD
macOS의 명령은 script
FreeBSD에서 시작됩니다. 모든 버전은 -a
덮어쓰기 대신 추가를 지원합니다(그러나 위에서 언급한 것처럼 프로세스 대체를 사용하여 명명된 파이프 위에 쓸 때 추가하는 데 도움이 되지 않습니다). -a
다음을 포함하는 유일한 옵션입니다.프리BSD 2.2.5. 옵션 -q
은 다음과 같습니다FreeBSD 2.2.6에 추가됨. 옵션 -k
은 다음과 같습니다FreeBSD 2.2.7에 추가됨.
위로FreeBSD 2.2.5를 통해, 이는 script
특정 명령이 주어지는 것을 허용하지 않지만, 변수가 설정되지 않은 경우 대체로 SHELL
환경 변수에 의해 주어진 사용자 셸을 항상 실행합니다./bin/sh
FreeBSD 2.2.6부터 시작script
, 셸 대신 실행될 명령줄에 특정 명령을 제공할 수 있습니다 .
script
따라서 최신 버전의 FreeBSD(현재 일반적인 버전 포함)는 명령을 호출하는 방식에서 최신 macOS 시스템(예: 사용자 시스템)과 유사합니다. 마찬가지로, 이전 버전의 FreeBSD는 이전 버전의 macOS와 유사합니다(아래 참조).
perl
최신 버전에서는 FreeBSD 기본 시스템의 일부가 아니며, 그런 bash
적도 없습니다. 둘 다 pkg install perl5 bash bash-completion
패키지(예: with) 또는 포트를 사용하여 쉽게 설치할 수 있습니다 . FreeBSD에서 제공하는 시스템은 /bin/sh
프로세스 대체를 지원하지 않습니다.
이전 버전의 macOS 및 다양성이 떨어지는 기타 시스템script
저는 Mac OS X 10.4 Tiger에서 테스트했습니다 script
.오직옵션 -a
. -q
또는 을 허용하지 않습니다 -k
. GNU/Linux 시스템의 util-linux 버전과 마찬가지로 typescript 7 의 터미널에 표시된 키 입력만 포함됩니다 .
적어도 각 macOS 버전에 대한 신뢰할 수 있는 문서 소스를 찾을 수 있을 때까지는 script
(내가 아는 한10.9 매버릭스 맨페이지온라인에서 쉽게 구할 수 있음)macOS 사용자에게 다음을 실행하는 것이 좋습니다.man script
script
해당 명령이 허용하는 구문, 기본적으로 작동하는 방식, 지원하는 옵션을 확인하세요 . 나와 같은 이전 버전의 macOS에서는 다음 명령을 사용할 수 있습니다.
script >(./dewtell >>clean.log)
brew args...
exit
이는 다음에도 적용됩니다.script
많은 옵션을 지원하지 않는 기타 운영 체제, 또는 다른 옵션을 지원하지만 해당 옵션을 사용하고 싶지 않은 운영 체제에서. 이 방법 script
은 셸을 시작하고 셸에 기록해야 하는 모든 명령을 실행한 다음 셸을 종료하는 전통적인 방법입니다.
명령을 가장하는 추악한 해킹은 쉘입니다.
쉘의 새 인스턴스가 아닌 단일 명령을 실행하기 위해 실제로 이를 사용해야 하는 경우 script
때때로 추악한 해킹을 사용할 수 있습니다. 실행하려는 명령이 실제로 쉘이라고 생각하도록 속일 수 있습니다. 하지만 이 작업을 수행하기 전에 두 번 생각해야 합니다.SHELL=your-command script outfile
your-command
실제로는 SHELL
환경 변수를 참조하여 사용 중인 실제 쉘을 확인하고, 유감스럽게도 불행한 동작이 발생합니다.
게다가 여러 단어로 구성된 명령(예: 하나 이상의 인수를 전달하는 명령)의 경우 이는 쉽지 않습니다. 이전에 같은 줄에 썼다면 값이 환경에 성공적으로 전달되지만 첫 번째 단어뿐만 아니라 전체 문자열이 명령 이름으로 사용되며 명령 대신 인수가 전달되지 않습니다. 다른 모든 단어는 통과되었습니다.SHELL='brew args...'
script
brew args...
script
SHELL
다음에서 실행되는 쉘 스크립트( run-brew
또는 원하는 대로 호출) 를 작성하여 이 문제를 해결할 수 있습니다.brew
args...
을 선택한 다음 이를 환경 변수의 값으로 전달합니다 SHELL
. run-brew
셸 스크립트를 생성 한 후 명령을 통해 실행하면 script
다음과 같습니다.
SHELL=run-brew script >(./dewtell >>clean.log)
위에 제시된 이유로 인해 SHELL
수행 중인 작업이 중요하지 않거나 를 사용하지 않을 것이라고 확신하지 않는 한 명령 이름을 할당하는 방법을 사용하지 않는 것이 좋습니다 SHELL
. Homebrew는 상당히 복잡한 작업을 많이 수행하므로 실제로 run-brew
그러한 스크립트를 실행하지 않는 것이 좋습니다. (길고 복잡한 brew
명령을 스크립트에 넣는 데에는 아무런 문제가 없습니다 run-brew
. 그냥 SHELL=run-brew
make를 사용하여 script
실행하세요.)
그러나 위에 표시된 기술을 테스트하기 위해 간단한 프로그램과 함께 사용할 때 이 접근 방식이 다소 유용하다는 것을 알았습니다.brew args...
기술 테스트 및 시연
긴 명령보다 더 복잡한 명령에 대해 이러한 방법 중 일부를 시도해 보는 것이 유용할 수 있습니다 brew
. 나는 내가 그랬다는 것을 안다.
데모 프로그램/테스트 입력 생성기 및 사용된 테스트 방법
나는 표준 오류에 쓰고 표준 출력에서 사용자의 이름을 묻는 메시지를 표시하고 표준 입력에서 읽은 다음 표준 출력에 인사말을 쓰고 사용자를 색상 이름으로 표시하는 간단한 대화형 Perl 스크립트를 만들었습니다.
#!/usr/bin/perl
use strict;
use warnings;
use Term::ANSIColor;
print STDERR $0, ": warning: this program is boring\n";
print "What's your name? ";
chomp(my $name = <STDIN>);
printf "Hello, %s!\n", colored($name, 'cyan');
불러서 colorhi
넣는다두테르테의 대본, 나는 그것을 이라고 부른다 dewtell
.
내 테스트에서는 #!/usr/bin/perl
두 스크립트를 모두 교체했습니다. 8 시스템 제공 Perl 5.22.1 및 제공 버전 5.6.2 및 5.8.9를 사용하고 FreeBSD 11.1-RELEASE-p3 및 제공 Perl 5.24.3 및 버전 5.6.2, 5.8.9 및 5.27.5를 사용하여 Ubuntu 16.04 LTS에서 테스트했습니다. ; 맥 OS#!/usr/bin/env perl
perlbrew
pkg
perlbrew
perlbrew
각 Perl 버전에 대해 아래에 설명된 테스트를 반복했습니다. 먼저 시스템에서 제공하는 9 버전을 테스트한 다음 일시적으로 사용하여 제공된 perlbrew use
각 바이너리가 먼저 나타나도록 했습니다 (예를 들어 Perl 5.6.2를 테스트하기 위해 실행한 후 다음이 표시됩니다). 테스트 중인 시스템에 대한 명령).perlbrew
perl
$PATH
perlbrew use 5.6.2
친구가 원래 hashbang 라인을 사용하여 macOS 10.11.6 El Capitan에서 테스트한 결과 시스템에서 제공한 perl 5.18.2를 사용하고 다른 인터프리터는 테스트하지 않았습니다. 이 테스트에서는 FreeBSD에서 테스트할 때 실행한 것과 동일한 명령을 사용합니다.
Mac OS X 10.4.11 Tiger에서 시스템 제공 Perl을 제외하고 이러한 모든 테스트는 성공적이었습니다., 아래 예제와 같이 이전에 자세히 설명한 것처럼 정규식의 문자 클래스와 관련된 이상한 오류로 인해 실패했습니다.
우분투에서
스크립트가 포함된 디렉터리에서 Ubuntu 시스템에서 다음 명령을 실행하여 이스케이프 시퀀스와 입력할 수 있는 백스페이스 문자가 포함된 TypeScript를 생성합니다.
printf 'Whatever header you want...\n\n' >dirty.log
script dirty.log -aqc ./colorhi
나는 그것을 입력 Eliah
한 다음 더 나은 생각인 것처럼 행동하고 백스페이스 키로 삭제하고 를 입력했습니다 Bob from accounting
. 그런 다음 그것을 눌렀 Enter더니 색깔이 반겨주었습니다. 그런 다음 다음 명령을 실행합니다.각기이스케이프 시퀀스 없이, 실제 이름을 표시하지 않고 타이프스크립트를 생성하고, 정확히 동일한 방식으로 상호작용합니다(타이핑 및 지우기 포함 Eliah
).
printf 'Whatever header you want...\n\n' >clean.log
script >(./dewtell >>clean.log) -qc ./colorhi
vim
제어 문자를 기호적으로 표시 cat -v
하고 밝은 텍스트나 색상 텍스트의 장점을 제공합니다. 표시된 버퍼는 다음과 같지만 view dirty.log
제어 문자는 이탤릭체로 표시되어 눈에 띕니다.
Whatever header you want...
Script started on Thu 09 Nov 2017 07:17:19 AM EST
./colorhi: warning: this program is boring^M
What's your name? Eliah^H ^H^H ^H^H ^H^H ^H^H ^HBob from accounting^M
Hello, ^[[36mBob from accounting^[[0m!^M
버퍼의 모습은 다음과 같습니다 view clean.log
.
Whatever header you want...
Script started on Thu 09 Nov 2017 07:18:31 AM EST
./colorhi: warning: this program is boring
What's your name? Bob from accounting
Hello, Bob from accounting!
결과는 타임스탬프를 제외하고 테스트된 모든 인터프리터에 대해 동일합니다.
FreeBSD(및 macOS 10.11.6 El Capitan)
다음 명령을 사용하여 빌드했다는 점을 제외하면 Ubuntu에서와 동일한 방식으로 FreeBSD에서 테스트했습니다 dirty.log
.
printf 'Whatever header you want...\n\n' >dirty.log
script -aq dirty.log ./colorhi
다음 명령을 사용하여 다음을 생성합니다 clean.log
.
printf 'Whatever header you want...\n\n' >clean.log
script -q >(./dewtell >>clean.log) ./colorhi
이것은 내 친구가 macOS 10.11에서 테스트할 때 실행한 것과 동일한 명령입니다.Eliah
, 내보낸 입력이 내 / 입력 과 약간 다르지만 Bob from accounting
여전히 이름을 입력하고 백스페이스로 삭제한 다음 다른 이름으로 바꿉니다. 따라서 백스페이스 키의 이름과 수를 제외하면 출력은 유사합니다.
네 가지 Perl 구현은 모두 FreeBSD에서 테스트되었으며 하나(시스템 제공) 구현은 macOS 10.11에서 테스트되었으며 둘 다 예상된 출력을 dirty.log
보여줍니다 . clean.log
FreeBSD 결과를 Ubuntu 결과와 비교해 보면 타임스탬프가 없다는 점이 다릅니다. 이는 제거를 나타내는 모든 백스페이스 및 백스페이스 문자와 마찬가지로 모든 -q
이스케이프 시퀀스 및 캐리지 리턴이 에서 성공적으로 제거되었기 때문입니다.clean.log
Mac OS X 10.4.11 타이거
다음 명령을 사용하여 빌드했다는 점을 제외하면 Ubuntu 및 FreeBSD와 동일한 방식으로 기존 Tiger 시스템에서 테스트했습니다 dirty.log
.
printf 'Whatever header you want...\n\n' >dirty.log
SHELL=colorhi script -a dirty.log
다음 명령을 사용하여 다음을 생성합니다 clean.log
.
printf 'Whatever header you want...\n\n' >clean.log
SHELL=colorhi script >(./dewtell >>clean.log)
시스템 script
명령이 지원되지 않으므로 -q
결과는 다음과 같습니다.(ㅏ)Script started
제목 뒤에 줄 추가(둘)개행 문자 다음에는 Script done
각 타이프스크립트의 끝에 한 줄이 추가됩니다. 두 줄 모두 타임스탬프를 포함합니다. 그렇지 않으면 결과는 Ubuntu 및 FreeBSD와 동일합니다.청록색 텍스트 간 전환을 위한 시스템 제공 이스케이프 시퀀스가 완전히 제거되지 않았습니다.perl
. 예상대로 관련 줄은 항상 dirty.log
다음과 같이 나타납니다 vim
.
Hello, ^[[36mBob from accounting^[[0m!^M
시스템 제공 Perl 5.8.6에서 이는 clean.log
디스플레이 6m
및 의 해당 행이며 0m
제거되어야 하며 다음과 같습니다.
Hello, 6mBob from accounting0m!
설치된 모든 perlbrew
Perl에 대해 모든 이스케이프 시퀀스가 정확하고 올바르게 제거되며 Ubuntu 및 FreeBSD에서 실행하는 모든 Perl 인터프리터에서와 마찬가지로 행은 다음 clean.log
과 같습니다.
Hello, Bob from accounting!
노트
1 그 매뉴얼배쉬 2와 함께 작동합니다. 많은 Bash 사용자는 주요 버전 4를 사용하고 있으며 읽기를 선호합니다.프로세스 교체,관로및 기타 주제현재 Bash 매뉴얼. 현재 버전의 macOS에는 Bash 3이 함께 제공됩니다.
2 표준 에러파일이나 장치 유형에 관계없이 거의 항상 버퍼링되지 않습니다. 프로그램이 파일 설명자 2에 대한 쓰기를 버퍼링할 수 없다는 규칙은 없지만 오류 및 경고 메시지가 발생할 때 실제로 확인하고 볼 필요가 있기 때문에 그렇게 하지 않는 강한 전통이 있습니다.별말씀을요, 프로그램이 적절하게 닫히지 않거나 열린 파일 설명자를 플러시하지 않고 비정상적으로 종료되는 경우에도 마찬가지입니다. 이는 일반적으로 프로그램이 기본적으로 표준 오류에 대한 쓰기를 버퍼링하는 버그입니다.
3 프로세스 대체 사용명명된 파이프, 또한 ~으로 알려진선입선출, 이는 셸의 파이프 연산자와 동일한 일반 목표를 달성 |
하지만 더 일반적입니다. 그러나 그럼에도 불구하고파이프이다, 나는 그렇게 생각하지 않는다파이프라인, 내 생각에는 쉘의 특정 구문 구조와 해당 동작을 참조하는 것 같습니다.
4 네임드파이프를 파일로 취급한다면,당신은해야, 그렇다면 이것이 실제로 일어나고 있는 일입니다.
5"$COMMAND"
에 등장 하지만너의 답전체 명령을 단일 인수로 전달합니다 script
(왜냐하면큰따옴표막다분사), 다음 명령을 전달할 수 있습니다.script
여러 매개변수로.
6 과 마찬가지로리눅스브루, 인정해야겠어당신은 나에게 소개.
7 그러나 민감한 데이터를 비밀로 유지하기 위해 이 동작에 의존하는 사람은 누구나 script
자신의 명령 동작을 테스트하고 결과 TypeScript를 확인하여 보호해야 할 데이터가 없는지 확인하는 것이 좋습니다. 추가 보안을 위해 일반적으로 화면에 숨겨진 문자를 표시하는 편집기를 사용하거나 cat -v
.
#!/usr/bin/perl
표시된 구현을 포함하여 8 과 함께 제공되는 버전은 colorhi
대부분의 시스템에서 실행되고 올바른 작업을 수행해야 합니다. 나는 #!/usr/bin/env perl
그것을 내 자신의 테스트에 사용했습니다. 그런데 내 친구는 당신과 같은 OS를 사용하고 있습니다(원본 포스터) #!/usr/bin/perl
. 이는 시스템에서 제공하는 Perl이 최소한의 복잡성이나 잠재적 의심으로 작동하는지 확인하는 목표를 달성합니다.
9FreeBSD에는 가장 엄격한 의미에서 시스템이 제공하는 Perl이 없습니다. 먼저 설치된 버전을 테스트했습니다 pkg
.
답변2
#!/usr/bin/env expect
package require Tcl 8.5
if {[llength $argv] == 0} {
puts stderr "Usage: $argv0 logfile command \[cmd-args ..]"
exit 1
}
set ::argv [lassign $::argv thelogfile]
log_file $thelogfile
spawn -noecho {*}$argv
interact
모든 내용은 지정된 로그 파일에 추가되어야 하며( 기본적으로 log_file
기록됨 ) 생성된 명령을 조작할 수 있습니다. 사용 예:expect(1)
interact
$ rm out
$ ./yointeract out sh
$ echo hi
hi
$ printf "\033[10Ghi\n"
hi
$ exit
$ xxd out
00000000: 2420 6563 686f 2068 690d 0a68 690d 0a24 $ echo hi..hi..$
00000010: 2070 7269 6e74 6620 225c 3033 335b 3130 printf "\033[10
00000020: 4768 695c 6e22 0d0a 1b5b 3130 4768 690d Ghi\n"...[10Ghi.
00000030: 0a24 2065 7869 740d 0a .$ exit..
$
PS 이것은 이 프로그램이 하는 일과 거의 비슷 autoexpect(1)
합니다.expect(1)
답변3
@EliahKagan과 많은 대화를 나눈 후 그는 제가 다음과 같은 결론을 내리는 데 도움을 주었습니다.
먼저 다음 전제 조건을 수집합니다.
- 분명히 표준 출력과 오류를 사용하여 명령을 실행하고 싶을 것입니다
"$COMMAND"
. - 로그를 첨부할 파일(해당 로그를 생성한 원인을 설명하는 설명을 파일 상단에 남길 수 있도록 하기 위함입니다. 적어도 저는 그렇게 기록하는 경향이 있습니다.) 다음에서 이를 참조하겠습니다. 처럼
"$LOG_FILE"
. - 비교적 새로운 버전을 설치하세요진주(아니요진주6,지금 바로아니요이전 주요 언어 버전과 호환됩니다(아직 없는 경우).
- @dewtell이 제공한 Perl 스크립트의 실행 가능한 사본그의 대답도착하다이것은 또 다른 Unix & Linux Stack Exchange 질문입니다.. 다음에서는 이를 이라고 지칭하겠습니다
"$RM_ANSI_ESC_SEQS_SCRIPT"
. - 설치하다더 많은 유틸리티(을 위한
sponge
.)
"$PATH"
귀하의 쉘(나는 그것을 사용하고 있지만 bash
다른 쉘은 여기에 설명된 프로세스에 완벽하게 적합할 수 있으므로 이 지침을 거의 또는 전혀 변경할 필요가 없음)이 Perl 및 기타 유틸리티를 찾을 수 있도록 쉘을 수정하십시오 . script
이 답변에 언급된 또 다른 명령인 는 적어도 나와 같고 컴퓨터에서 상대적으로 새로운 버전의 OS X/macOS를 실행하는 경우 시스템에서 이미 사용할 수 있어야 합니다. 그렇지 않거나 어떤 이유로든 다른 소스에서 최신 버전을 설치하려면 문제를 해결하거나 지금 설치하십시오.
그런 다음 다음 명령을 순서대로 실행하십시오.
script -aq "$LOG_FILE" "$COMMAND" # Add the `k` option, either separately or as part of the group of short options already given to this command, if you want to log user input as well.
"$RM_ANSI_ESC_SEQS_SCRIPT" "$LOG_FILE" | sponge "$LOG_FILE"
또한 이 명령의 일부 버전에는 script
구문이 다릅니다.제공된 버전은 OS X/macOS용입니다.이므로 필요에 따라 조정하세요. 그 외에는 그게 다입니다. 그러나 이 모든 것을 하나의 파이프로 연결하는 방법이 있을 수 있다는 점을 덧붙이고 싶습니다. 하지만 이 글을 쓰는 시점에서는 아직 파악하지 못했습니다. 이를 수행하는 방법에 대한 다른 의견이나 답변도 환영합니다. .