파일 디스크립터가 터미널 장치를 가리키는 지 여부
프로그램은 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
.