Bash I/O 리디렉션 이해

Bash I/O 리디렉션 이해

나는 Bash의 파일 설명자를 사용하여 실제 수준에서 I/O 리디렉션이 수행되는 방법을 잘 알고 있지만 온라인에서 사례를 발견했습니다(https://linuxcommand.org/lc3_adv_dialog.php, "방법 2: 명령 대체 및 리디렉션 사용"에서), 왜 사용되는지 완전히 이해하지 못합니다.

명령 대체 오류를 잡기 위해 stderr를 stdout으로 리디렉션해야 하는 구현이 있는데, 이는 나에게 완벽하게 이해되지만 파일 설명자가 낮은 수준에서 작동하는 방식을 이해하려면 추가 리디렉션을 수행해야 한다고 생각합니다. 의사코드:

exec 3>&1
...
var=$(cmd -options ... 2>&1 1>&3)
...
exec 3>&-

stdout을 백업하고 stdout을 이미 가리키는 곳으로 리디렉션하는 이유는 무엇입니까? stdout은 이제 stderr의 내용을 수신한다는 점을 제외하고는 변경된 적이 없습니다.

내 추측으로는 fd 3에 stdout의 원래 상태가 포함되어 있고 fd 1을 fd 3으로 리디렉션하면 원래 상태로 돌아가고 fd 2도 거기로 리디렉션된다는 것인가요? 통찰력이나 독서 자료를 원합니다.

답변1

원래 작성한 양식에서 명령은 단지 입니다. 이는 cmd -options ... 2>&1 1>&3실제로 stderr과 stdout이 모두 stdout으로 리디렉션되기 때문에 의미가 없습니다. 따라서 1>&3필요하지 않습니다.

하지만 말씀하신 예는 다른 상황입니다. 우리가 가진 것은 입니다 variable=$(cmd -options ... 2>&1 1>&3). 이 $(command)구성은 stdout 자체를 리디렉션하여 command캡처하여 변수에 배치할 수 있도록 합니다. 따라서 이 경우 첫 번째 stderr은 command다음으로 리디렉션됩니다.이미 리디렉션됨표준 출력( 2>&1), 즉. 변수에 배치되고 이 stdout은 command다음으로 리디렉션됩니다.원래리디렉션 전 stdout, 설명자 3( 1>&3)에 저장됩니다. 효과는 이렇습니다표준 에러command변수에 배치 되며표준 출력variable=$(command)stdout이 변수에 배치되고 stderr이 표시되는 "정상" 케이스와는 달리 정상적으로 표시됩니다 . 이것은 귀하가 링크한 동일한 페이지에 매우 잘 설명되어 있습니다.

언뜻 보면 리디렉션이 무의미해 보일 수 있습니다. 먼저 exec를 사용하여 파일 설명자 1(stdout)을 설명자 3에 복사하여 설명자 1의 백업 복사본을 만듭니다(추가 리디렉션에서 다룸).

다음 단계는 명령 대체를 수행하고 대화 상자 명령의 출력을 변수 결과에 할당하는 것입니다. 이 명령은 설명자 2(stderr)를 설명자 1의 복사본으로 리디렉션하고 마지막으로 백업 복사본이 포함된 설명자 3을 복사하여 설명자 1을 원래 값으로 복원하는 것으로 구성됩니다. 명확하지 않을 수 있는 것은 마지막 리디렉션이 필요한 이유입니다. 서브셸 내에서 표준 출력(설명자 1)은 제어 터미널로 전달되지 않습니다. 대신, 해당 내용을 변수 결과에 전달하는 파이프를 가리킵니다. 대화 상자가 입력 상자를 표시할 수 있도록 터미널을 가리키는 표준 출력이 필요하므로 표준 오류를 표준 출력으로 리디렉션한 다음(대화 상자의 출력이 결과 변수로 끝나도록) 표준 출력을 다시 리디렉션해야 합니다. 제어 터미널로.

관련 정보