출력이 터미널로 가고 있다고 생각하도록 명령을 속이는 방법 유지하면서 출력을 파이프 라인에서 어떻게 리디렉션 할

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

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

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



답변

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

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

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

alias ls='ls --color=auto'

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

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


답변

툴셋의 역사

당신은 그런 도구를 원하는 첫 번째 사람이 아닙니다. 사람들은 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

추가 자료


답변

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

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

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


답변

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

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


답변

어때요 script(1)?

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

script -q -c 'ls -G' out_file

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


답변

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

#!/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" "$@"


답변