`tty <&1` 및 `echo $(tty <&1)` 및 `echo $(tty <&2)` 정보

`tty <&1` 및 `echo $(tty <&1)` 및 `echo $(tty <&2)` 정보

아래 코드 조각의 주요 문(즉, 레이블을 인쇄하는 데 사용되는 문과 공백에 사용되는 빈 줄 제외)은 쌍으로 나타납니다. 각 쌍에서 첫 번째와 두 번째 문은 각각 tty...및 형식입니다 echo $(tty...).

echo stdin:
tty
echo $(tty)

echo

echo stdout:
tty <&1
echo $(tty <&1)

echo

echo stderr:
tty <&2
echo $(tty <&2)

이 코드 조각이 포함된 파일을 가져오면(예: zshOR 세션에서) 다음과 같은 출력이 표시됩니다. 1 (나중에 참조용으로 줄 번호를 추가했습니다):bash

 1    stdin:
 2    /dev/pts/8
 3    /dev/pts/8
 4    
 5    stdout:
 6    /dev/pts/8
 7    not a tty
 8    
 9    stderr:
10    /dev/pts/8
11    /dev/pts/8

이 출력에서 ​​(라인 7)에 의해 생성된 라인은 echo $(tty <&1)두 가지 이유로 두드러집니다.

  1. echo $(tty ...)tty ...이는 이전에 생성된 행(2, 6, 10행)과 다른 유일한 생성된 행(즉, 3, 7, 11행)입니다 .
  2. 이는 형식적으로 유사한 출력(라인 11)과 다릅니다 echo $(tty <&2).

묻다:이 두 가지 차이점을 어떻게 설명할 수 있나요?


기록상으로, 나는 의 매뉴얼 페이지에서 이러한 명백한 이상 현상에 대한 설명을 찾으려고 노력했지만 tty, 내가 아는 한 해당 페이지는 이러한 문제를 전혀 명시적으로 다루지 않았습니다 .

이 문제는 일부 코드로 인해 발생합니다.이것은 훌륭한 답변입니다이전 질문 중 하나입니다.


1 물론 /dev/pts/단말기를 바꾸면 그 이후 실제 수치는 달라질 수 있고, 같은 것을 시도해도 여러분에게는 다를 수 있습니다.

2 사실 tty내 시스템에서 사용할 수 있는 매뉴얼 페이지의 전체 설명 섹션에는 "표준 입력에 연결된 터미널의 파일 이름을 인쇄하십시오."라는 한 문장만 포함되어 있습니다.

3여기서 나는 나보다 더 많은 배경 지식을 가진 사람이 그럴 수 있을 가능성을 열어 둡니다.미루다tty위에 표시된 동작은 의 간결한 매뉴얼 페이지에서 볼 수 있습니다 .

답변1

tty(표준 출력에서) 표준 입력(fd 0)에서 열려 있는 tty 장치의 이름을 보고합니다.

존재하다:

tty <&2

이것은 어떤 약어인가요?

tty 0<&2

쉘은 fd 0을 fd 2에서 열린 동일한 리소스로 리디렉션합니다( dup2(2, 0)새 프로세스에서 a를 실행한 다음 tty해당 프로세스에서 실행). 따라서 ttyfd 0과 2에 동일한 리소스가 있고 fd 1에 tty를 작성하면 둘 다 열려 있습니다(있는 경우).

다음과 같은 경우에도 동일한 상황이 발생합니다.

tty <&1

존재하다:

echo "$(tty <&1)"

그러나 이 명령은 파이프로 가는 fd 1을 대체합니다(그리고 쉘은 다른 쪽 끝에서 출력을 읽습니다). 이는 ttyfd 1이 가는 것과 다른 리소스입니다.echo

fd 1에서 열린 tty를 알고 명령 대체를 사용하려면 다음과 같은 것이 필요합니다.

{ echo "$(tty <&3)"; } 3<&1

따라서 실행 중인 프로세스의 경우 tty다음이 있습니다.

  • 3: 외부 레이어 1과 동일
  • 1: 파이프
  • 2: 손대지 않음
  • 0: 3과 동일하므로 외부 1과 동일

따라서 tty연결된 tty 장치의 경로는 해당 파이프에 기록될 수 있습니다.밖의표준 출력.

tty에는 fd 3이 필요하지 않으므로 다음 명령을 사용하여 더 간결하게 만들 수 있습니다.

{ echo "$(tty <&3 3<&-)"; } 3<&1

즉, 작업이 끝나면 닫고 fd 0에 복사합니다.

관련 정보