답변1
터미널에서 실행되는 쉘의 일반적인 경우를 가정해 보겠습니다. 쉘의 모든 stdin, stdout, stderr이 이 터미널에 연결되어 있습니다. 여기서 읽는다는 것은 사용자의 입력을 읽는다는 뜻이고, 여기에 쓰면 사용자가 읽을 수 있는 내용이 인쇄됩니다.
이제 쉘이 명령을 시작하면 명령은 모든 fd를 터미널에 연결합니다. 쉘이 실행하는 다음 명령도 마찬가지입니다. 이와 같이:
+---------------+ +---------------+
| first cmd | | other cmd |
|stdin stdout | |stdin stdout |
+---------------+ +---------------+
| | | |
| | | |
| | | |
[------------------ tty -----------------]
이제 당신은 이렇게 말합니다.
내 첫 번째 아이디어는 두 번째 프로세스의 stdin을 첫 번째 프로세스의 stdout으로 변경하는 것이었습니다.
그러나 위의 두 fd를 교환하는 경우 결과는 다르지 않습니다. 이전에는 모든 fd가 tty에 연결되었으므로 교환 후에는 모든 fd가 tty에 연결됩니다.
자, tty 측에서 fd 중 하나를 분리한다는 의미라면 실제로는 그렇게 작동하지 않습니다. fd는 커널 데이터 구조에 대한 포인터와 비슷하며, tty를 가리키는 fd는 파이프나 네트워크 소켓을 가리키는 fd와 다릅니다. 또는 다른 방식으로 보면 fd는 프로세스와 운영 체제 간의 "연결"의 프로세스 측면일 뿐입니다.
따라서 OS 측의 다른 것에 연결할 수 있는 또 다른 fd가 필요합니다. 예를 들어 파이프. 파이프는 여전히 두 프로세스 사이를 연결하는 것 이상입니다.두 개의 연결프로세스와 운영 체제 사이:
+---------------+ +---------------+
| first cmd | | other cmd |
|stdin stdout | |stdin stdout |
+---------------+ +---------------+
| | | |
| | | |
| [-w-- pipe driver -----r-] |
| |
[------------- tty driver ---------------]
(위에서는 tty fd가 읽기 및 쓰기용으로 모두 열려 있다고 가정했습니다. 이는 제가 작업한 Linux 시스템의 경우이므로 실제로 stdin에 쓰거나 stdin fd를 stdout에 복사하는 것이 가능합니다. 읽기/쓰기 전용 모드로 열리면 작동하지 않습니다. Linux 파이프는 항상 단방향이며 읽기 및 쓰기 끝이 다릅니다.
답변2
파이프를 사용하지 않는다고 가정합니다. 첫 번째 프로세스는 쓸 수 있습니다표준 출력. 두 번째 프로세스는 읽을 수 있습니다표준 입력.
아주 쉽게 닫힐 수 있어요표준 입력두 번째 프로세스. 액세스하려면 무엇을 열어야 하나요?표준 출력첫 번째 과정은? (힌트: 그럴 수 없습니다.)
따라서 쓰기 및 읽기를 위해 열 수 있는 잘 알려진 끝점이 있는 파이프를 만듭니다.