아래 코드 조각의 주요 문(즉, 레이블을 인쇄하는 데 사용되는 문과 공백에 사용되는 빈 줄 제외)은 쌍으로 나타납니다. 각 쌍에서 첫 번째와 두 번째 문은 각각 tty...
및 형식입니다 echo $(tty...)
.
echo stdin:
tty
echo $(tty)
echo
echo stdout:
tty <&1
echo $(tty <&1)
echo
echo stderr:
tty <&2
echo $(tty <&2)
이 코드 조각이 포함된 파일을 가져오면(예: zsh
OR 세션에서) 다음과 같은 출력이 표시됩니다. 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)
두 가지 이유로 두드러집니다.
echo $(tty ...)
tty ...
이는 이전에 생성된 행(2, 6, 10행)과 다른 유일한 생성된 행(즉, 3, 7, 11행)입니다 .- 이는 형식적으로 유사한 출력(라인 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
해당 프로세스에서 실행). 따라서 tty
fd 0과 2에 동일한 리소스가 있고 fd 1에 tty를 작성하면 둘 다 열려 있습니다(있는 경우).
다음과 같은 경우에도 동일한 상황이 발생합니다.
tty <&1
존재하다:
echo "$(tty <&1)"
그러나 이 명령은 파이프로 가는 fd 1을 대체합니다(그리고 쉘은 다른 쪽 끝에서 출력을 읽습니다). 이는 tty
fd 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에 복사합니다.