파일 디스크립터가 터미널 장치를 가리키는 지 여부
프로그램은 isatty()표준 C 함수 를 사용하여 파일 디스크립터가 tty 장치와 연관되어 있는지 알 수 있습니다 (일반적으로 ioctl()fd가 tty 장치를 가리 키지 않을 때 오류가 발생 하는 무해한 tty 특정 시스템 호출 아래에 있음) .
[/의 test유틸리티는 그와 함께 할 수있는 -t운영자입니다.
if [ -t 1 ]; then
echo stdout is open to a terminal
fi
GNU / Linux 시스템에서 libc 함수 호출 추적 :
$ ltrace [ -t 1 ] | cat
[...]
isatty(1) = 0
[...]
추적 시스템 호출 :
$ strace [ -t 1 ] | cat
[...]
ioctl(1, TCGETS, 0x7fffd9fb3010) = -1 ENOTTY (Inappropriate ioctl for device)
[...]
파이프를 가리키는 지 알려주기
fd가 pipe / fifo와 연관되어 있는지 판별하기 위해 fstat()시스템 호출을 사용할 수 있습니다.이 호출st_mode 은 해당 fd에서 열린 파일의 유형 및 권한을 필드에 포함 하는 구조를 리턴합니다 . S_ISFIFO()표준 C 매크로 것을 사용할 수있다 st_mode상기 FD는 FIFO / 파이프인지 확인 필드.
을 수행 할 수있는 표준 유틸리티는 fstat()없지만이 stat를 수행 할 수 있는 명령 의 호환되지 않는 구현이 몇 가지 있습니다. zsh의 stat내장과 stat -sf "$fd" +mode첫 문자 (유형 나타내는 문자열 표시 모드로 반환하는 p파이프를). GNU는 stat과 같은 작업을 수행 할 수 있습니다 stat -c %A - <&"$fd", 또한이 stat -c %F - <&"$fd"보고서에 형식을 혼자. BSD 사용 stat: stat -f %St <&"$fd"또는 stat -f %HT <&"$fd".
찾을 수 있는지 말하기
응용 프로그램은 일반적으로 stdout이 파이프인지 상관하지 않습니다. 그들은 검색 가능하도록 신경 쓸지도 모릅니다 (일반적으로 버퍼링할지 여부를 결정하지는 않음).
fd를 검색 할 수 있는지 (파이프, 소켓, tty 장치는 검색 할 수없고, 일반 파일 및 대부분의 블록 장치는 일반적으로 사용 가능한지) 여부를 테스트하기 위해 오프셋이 0 인 상대 lseek()시스템 호출 (무해한)을 시도 할 수 있습니다 . dd인터페이스는 표준 유틸리티 lseek()이지만 lseek()0의 오프셋을 요청하면 구현이 전혀 호출하지 않으므로 해당 테스트에 사용할 수 없습니다 .
zsh와 ksh93쉘은 다음 과 같이 탐색 연산자를 내장하고 있습니다.
$ strace -e lseek ksh -c ': 1>#((CUR))' | cat
lseek(1, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ksh: 1: not seekable
$ strace -e lseek zsh -c 'zmodload zsh/system; sysseek -w current -u 1 0 || syserror'
lseek(1, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
Illegal seek
버퍼링 비활성화
이 script명령은 의사 터미널 쌍을 사용하여 프로그램의 출력을 캡처하므로 프로그램의 stdout (및 stdin 및 stderr)은 의사 터미널 장치가됩니다.
stdout이 터미널 장치에 대한 경우 여전히 버퍼링이 여전히 있지만 라인 기반입니다. printf/ puts및 co는 개행 문자가 출력 될 때까지 아무 것도 쓰지 않습니다. 다른 유형의 파일의 경우 버퍼링은 몇 킬로바이트의 블록 단위입니다.
버퍼링을 비활성화하는 몇 가지 옵션이 있습니다. 여기에서 Q & A ( unbuffer 또는 stdbuf 검색 , 컷 출력을 리디렉션 할 수는 없지만 몇 가지 접근법이 있습니다)에서 socat/ script/ expect/ 로 수행 할 수있는 의사 터미널 을 사용하여 버퍼링을 비활성화 할 수 있습니다 unbuffer(AN expect스크립트) / zsh의 zpty또는 GNU의 FreeBSD와의 수행으로 버퍼링을 비활성화하려면 실행 파일에 코드를 주입하여 stdbuf.