내 쉘이 터미널에 "연결"되어 있을 때만 실행하고 싶습니다. 즉, 내 stdin이 터미널의 입력에서 나오고 stdout(그리고 stderr? 아마도 중요하지 않을 수도 있음)이 인쇄/반향될 때만 실행하고 싶습니다. 터미널의 특정 작업.
GNU/Linux 세부 정보(예: )에 직접 의존하지 않고 어떻게 이를 수행할 수 있습니까 /proc/self
?
답변1
isatty
이를 확인하는 기능입니다,게다가-t
test
명령 기호쉘 스크립트를 통해 접근할 수 있습니다:
-티 파일 설명자
파일 설명자 번호가 참인 경우파일 설명자터미널이 열리고 연결되었습니다. 거짓이면파일 설명자유효한 파일 설명자 번호가 아니거나 파일 설명자 번호가파일 설명자열려 있지 않거나 열려 있지만 터미널과 연결되어 있지 않습니다.
다음을 사용하여 FD 0(표준 입력)이 TTY인지 확인할 수 있습니다.
test -t 0
FD 1과 2에 대해 동일한 작업을 수행하여 출력 및 오류 스트림 또는 둘 다를 확인할 수 있습니다.
test -t 0 -a -t 1 -a -t 2
이 명령은 설명자가 터미널에 연결되어 있으면 0(성공)을 반환하고 그렇지 않으면 false를 반환합니다.
test
[
"브래킷 테스트" 로도 사용할 수 있는 명령:
if [ -t 0 ] ; then ...
이 조건을 작성하는 관용적 방법입니다.
답변2
이미 제공된 훌륭한 답변 위에 추가 메모를 추가하기만 하면 됩니다. 파일 설명자 0 테스트 는 [ -t 0 ]
tty 줄 규칙을 사용하여 장치 파일인 파일을 엽니다(일반적으로 이는 무해한 termio(s) ioctl() 성공 여부를 확인하여 수행됩니다).
또한 이는 반대편에 터미널이나 터미널 에뮬레이터(실제 사용자가 키보드를 입력하는 경우)가 있다는 의미는 아닙니다(대부분의 경우, 아마도 관심 있는 대부분의 경우 대략적인 수치로 충분하지만). .
tty 및 pty 장치는 데이터 전송이나 프로세스 간 통신 메커니즘으로 사용될 수도 있습니다.
예를 들어 다음과 같이 할 수 있습니다.
(stty raw -echo; myscript) < /dev/ttyS0
RS232를 통해 수신된 콘텐츠를 으로 보냅니다 myscript
.
echo test | ssh -tt host myscript
stdin myscript
은 pty 장치입니다( sshd
다른 쪽 끝에서는 궁극적으로 (ssh를 통해 연결됨) 터미널이 아니라 터미널에서 제공하는 파이프입니다 echo
)
RS232 라인이나 pty의 반대쪽 끝에 터미널이 있는지 추가로 확인하려면 변수가 $TERM
설정되어 있고 비어 있지 않은지 확인 [ -n "$TERM" ]
하고( ) 전송하면 됩니다.장비현황 보고fd 이스케이프 시퀀스를 전달하고 응답을 받았는지 확인합니다( 및 제외 [ -t 0 ]
) [ -n "$TERM" ]
.
printf >&0 '\e[5n'
\e[0n
대부분의 터미널은 "a"로 응답합니다.
이제 몇 가지 문제가 있으므로 시각적 TUI 응용 프로그램을 실행하기 위해 이를 확인하고 싶지 않은 한 이 방법을 권장하지 않습니다. 이 경우 유사한 라이브러리를 사용하는 것이 더 좋으며 ncurses
장치 ID를 보내는 것이 좋습니다. 대신 DSR 대신 정의 시퀀스를 사용하여 다음보다 더 정확하게 터미널 유형을 쿼리합니다 $TERM
.
- 고맙게도 대부분의 경우 stdin은 터미널이 아니며 읽기 전용 모드로 열리므로
printf
오류가 발생하지만 stdin이 읽기+쓰기 모드로 열린 tty 장치인 경우 해당 장치를 전송하는 부작용이 있습니다. 다른 쪽 끝까지 순서. 예를 들어, 위의 ssh 예제에서 시퀀스는 실제로 터미널로 전송됩니다(그러나 응답은 표준 입력에 표시되지 않습니다). - 응답을 안정적이고 이식 가능하게 읽는 것은 어렵습니다. tty 라인 규칙을 일시적으로 변경하고 한 번에 한 바이트씩 읽어야 합니다. 또한 응답이 표시되지 않으면 포기하고 터미널이 없다고 결정하는 시간 초과를 결정해야 합니다. 사람들이 위성 연결을 통해 전화 접속을 하는 것을 고려한다면 이는 시간 초과가 길어진다는 것을 의미합니다.
- 백그라운드에서 터미널의 데이터를 읽으면 SIGTTIN 신호를 사용하여 스크립트가 일시 중지됩니다.