출력이 터미널로 가고 있다고 생각하도록 명령을 속이는 방법


38

출력이 터미널로 갈 때 (예 : 컬러 출력 생성) 동작을 변경하는 명령이 주어지면 변경된 동작을 유지하면서 출력을 파이프 라인에서 어떻게 리디렉션 할 수 있습니까? 내가 알지 못하는 유틸리티가 있어야합니다.

과 같은 일부 명령 grep --color=always에는 동작을 강제하기위한 옵션 플래그가 있지만 문제는 출력 파일 디스크립터 테스트에만 의존하는 프로그램을 해결하는 방법입니다.

중요한 경우 내 쉘은 bashLinux에 있습니다.


명령이 출력 파일 디스크립터를 테스트하는 방법을 알고 어떻게 든 출력 터미널에서 볼 수있는 결과와 일치하는 결과를 리턴해야합니다.
Andrew Henle

답변:


21

을 사용하여 필요한 것을 얻을 수 있습니다 unbuffer.

unbufferA는 tcl/ expect스크립트. 원한다면 소스를보십시오. 또한 man의 CAVEATS 섹션을 참고하십시오.

또한 다음과 같은 별칭을 실행하지 않습니다.

alias ls='ls --color=auto'

Stéphane Chazelas가 지적한대로 트릭을 추가하지 않는 한 :

를 수행하면 alias unbuffer='unbuffer '(후행 공백에 유의) 별명은 이후에 확장 unbuffer됩니다.


승인 된 별명에 대한 참고 사항 – 내장 및 함수와 같은 다른 쉘 구성에서는 작동하지 않습니다.
Amir

4
를 수행하면 alias unbuffer='unbuffer '(후행 공백에 유의) 별명은 이후에 확장 unbuffer됩니다.
Stéphane Chazelas

unbuffer그것은! sudo apt install expect-확실하지 않았습니다.
loxaxs

22

툴셋의 역사

당신은 그런 도구를 원하는 첫 번째 사람이 아닙니다. 사람들은 30 년 동안 그러한 도구를 원해 왔습니다. 그리고 그들은 거의 오랫동안 존재 해 왔습니다.

이러한 종류의 가장 초기 도구는 Rich Salz에 의해 설명 된 Daniel J. Bernstein의 "pty"패키지였습니다. "Ginsu knife"는 Bernstein이 nethack (sic!)에서 속임수를 쓰려고 1990 년대 초에 쓴 글입니다. "pty"패키지의 버전 4는 1992 년에 출판되었습니다 comp.sources.unix(볼륨 25 문제 127 ~ 135). 여전히 월드 와이드 웹에서 찾을 수 있습니다. Paul Vixie는 당시에 다음과 같이 설명했습니다.

내가 무엇을 말할 수 있습니까? 얇게 자르고 깍둑 썰기하며 설거지를하고 개를 걷습니다. 그것은 "그냥 작동합니다", 즉 당신이 지시를 따를 때 머리카락을 당기거나 치아를 gn거나 다른 표준 포팅 활동없이 작업 패키지를 얻을 수 있습니다.

번스타인 (Bernstein)은 1999 년 4 월 7 일 또는 그 이전에 "ptyget"패키지로 이것을 업데이트했다.

나는 새로운 의사 -tty 할당자인 ptyget을 구성했습니다. 알파 버전은 ftp://koobera.math.uic.edu/pub/software/ptyget-0.50.tar.gz입니다. ptyget 메일 링리스트가 있습니다. 참여하려면에 빈 메시지를 보내십시오 djb-ptyget-requ...@koobera.math.uic.edu. 나는 ptyget의 인터페이스를 처음부터 설계했다. pty보다 훨씬 모듈 식입니다. 기본 pty 인터페이스는 이제 세 부분으로 나뉩니다.

  • ptyget: 패키지의 유일한 setuid 프로그램 인 작은 저수준 프로그램으로 새로운 의사 tty를 할당하고 선택한 프로그램으로 전달합니다.
  • ptyspawn: 의사 tty에서 자식 프로세스를 실행하고 종료되기를 기다리고 중지를 관찰하는 또 다른 작은 프로그램
  • ptyio: 데이터를 앞뒤로 이동시키는 또 다른 약간 큰 프로그램

구긴 수 칼 pty은 이제 철자 ptybandage가되는데 이것은 동의어이다 ptyget ptyio -t ptyspawn. pty -d의사 프로그램에 네트워크 프로그램을 첨부하기 위해 이제 철자가 사용됩니다 ptyrun. 이는 동의어입니다 ptyget ptyio ptyspawn. 및 nobuf동의어입니다 ptyget ptyio -r ptyspawn -23x. 세션 관리 기능을 별도의 패키지로 분리했습니다.

그 별도의 패키지는 "sess"패키지였습니다.

"ptyget"은 Berstein의 자체 출판되지 않은 "redo"빌드 시스템의 초기 버전과 게시 된 몇 안되는 인스턴스 중 하나를 보여주는 것으로 유명합니다. dependon의 명확한 선구자 redo-ifchange입니다.

용법

ptybandage

ptybandage사람들이 일반적으로 로그인 세션에서 원하는 것입니다. 주요 사용 사례는 표준 입력, 출력 또는 오류가 터미널에 연결되어 있는지 여부에 민감한 프로그램을 실제로는 셸 파이프 라인에 있거나 표준 파일 디스크립터가 파일로 경로 재 지정되어 있어도 그렇게 작동하는 것입니다.

그것은 (물론, 적절한 외부 명령이어야한다)를 실행하는 명령을 취하고 그 표준 입력, 출력 및 오류에 이르기까지 그 연결 단자에 연결되어 있다고 생각하는 방식으로 실행 ptybandage의를 원래 표준 입력, 출력 및 오류.

작업 제어 쉘에서 실행하는 뉘앙스를 처리하여 터미널 STOP 문자 ptybandage가 내부 터미널에 연결된 프로그램 실행을 중지 할뿐 아니라 중지합니다.

ptyrun

ptyrun사람들이 일반적으로 TCP 네트워크 서버에서 원하는 것입니다. 주요 사용 사례는 터미널을 설정하지 않은 원격 실행 환경으로, 터미널이 없을 때 원하는대로 작동하지 않는 프로그램을 실행합니다.

작업 제어 쉘에서 실행되지 않을 것으로 예상되며 실행중인 명령이 중지 신호를 수신하면 다시 시작됩니다.

사용 가능한 툴셋

Dru Nelson은 "pty"버전 4와 "ptyget"을 모두 게시합니다.

Paul Jarc는 운영 체제 별 의사 터미널 장치 ioctl을 운영 체제에서 더 이상 실제로 제공하지 않는 문제를 처리하려고 시도하는 고정 된 버전의 ptyget을 게시합니다.

nosh 소스 패키지에는 Laurent Bercot의 도구와 nosh 패키지 자체의 의사 터미널 관리 명령 을 사용하는 유사한 스크립트 ptybandangeptyrun스크립트 가 제공됩니다 execline. nosh 버전 1.23부터는 nosh-terminal-extras 패키지에 사전 패키지되어 있습니다. (이전 버전은 소스로 만든 사람들에게만 제공했습니다.)

몇 가지 예는

Jurjgen Oskam ptybandage은 AIX 에서 사용하여 here 문서의 입력을 명시 적으로 열고 프로그램에서 제어 프롬프트를 통해 비밀번호 프롬프트를 읽는 프로그램에 입력합니다.

$ ptybandage dsmadmc << EOF> uit.txt
요 스카
암호
쿼리 세션
쿼리 프로세스
떠나다
EOF

Andy Bradfordptyrun 는 daemontools 및 ucspi-tcp 에서 OpenBSD 를 사용하여 bgplgsh대화식 라우터 제어 프로그램을 네트워크를 통해 액세스 할 수있게 만드는 한편 터미널과 통신한다고 생각합니다.

#! / bin / sh
exec 2> & 1
exec envuidgid rviews tcpserver -vDRH0 0 23 ptyrun / usr / bin / bgplgsh

추가 자료


역사에 대한 교훈에 감사하지만 제안한 도구는 최신 Linux 배포판에서 사용할 수 없으므로 유용하지 않습니다.
Amir

4
여러 가지 하이퍼 링크와 툴의 가장 확실한 위치에 대한 답변의 전체 섹션 있습니다.
JdeBP

1
당신의 의견은 expect무엇입니까?
CMCDragonkai

20

socat 을 사용 하여 pty가 연결된 상태에서 프로세스를 시작 하고 socat이 pty의 다른 쪽 끝을 파일에 연결하도록 할 수 있습니다. 어떤 AFAIU가 당신이 요구 한 것입니까?

socat EXEC:"my-command",pty GOPEN:mylog.log

이 메소드는 isatty호출 한 호출 my-command을 리턴 true하고 그에 의존하는 프로세스는 제어 코드를 출력하도록 속입니다. 일부 프로세스 (특히 grep)도 TERM환경 변수 의 값을 확인 하므로 다음과 같이 합리적인 것으로 설정해야 할 수도 있습니다."xterm"


13

KarlC의 Super User 에 게시 된 멋진 솔루션이 있습니다 .

작은 공유 라이브러리를 컴파일하십시오.

echo "int isatty(int fd) { return 1; }" | gcc -O2 -fpic -shared -ldl -o isatty.so -xc -

그런 다음 명령에이 isatty(3)재정의를 동적으로 로드하도록 지시하십시오 .

LD_PRELOAD=./isatty.so mycommand

이것은 모든 명령에 대해 작동하지 않을 수도 있고 예기치 않은 방식으로 일부를 중단 할 수도 있지만 대부분의 경우 작동 할 것입니다.


2
MacOS 사용자의 경우 다음을 사용하여 동일한 동작을 얻을 수 있습니다.DYLD_INSERT_LIBRARIES=./isatty.so DYLD_FORCE_FLAT_NAMESPACE=y mycommand
Christopher Shroba

12

어때요 script(1)?

예를 들면 다음과 같습니다.

script -q -c 'ls -G' out_file

색상 코드가 보존 된 상태로 ls출력을 저장합니다 out_file.


이것은 여기서 작동하지 않습니다. 색상은 어떻게 보존됩니까? out_file색상 으로 출력하는 데 사용해야하는 도구가 있습니까?
Kira

1
ANSI 색상 이스케이프 시퀀스로 파일을 보려면 @Kira를 사용 less -R합니다. 그러나이 경우 파이프 라인에서 출력이 계속되고 싶었고 결국 터미널에서 끝났습니다. 예를 들어 사용 하면 파일이 완전히 억제 되어 프로그램의 출력 만 남기는 cat것과 같은 것 입니다. script -q -c 'ls -G' /dev/null | cattypescript
Amir

파일을 만들지 않으려면 출력 파일 -로 대시 ( )를 사용하십시오 script.script -q -c 'ls -G' -
Franklin Piat

0

를 기반으로 아미르의 대답 @ , 여기에 생성 후 런타임 라이브러리를 포함하는 스크립트입니다 :

#!/bin/bash
set -euo pipefail

function clean_up {
  trap - EXIT # Restore default handler to avoid recursion
  [[ -e "${isatty_so:-}" ]] && rm "$isatty_so"
}
# shellcheck disable=2154 ## err is referenced but not assigned
trap 'err=$?; clean_up; exit $err' EXIT HUP INT TERM

isatty_so=$(mktemp --tmpdir "$(basename "$0")".XXXXX.isatty.so)
echo "int isatty(int fd) { return 1; }" \
  | gcc -O2 -fpic -shared -ldl -o "$isatty_so" -xc -
# Allow user to SH=/bin/zsh faketty mycommand
"${SH:-$SHELL}" -c 'eval $@' - LD_PRELOAD="$isatty_so" "$@"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.