A 프로세스와 B 프로세스(A에서 호출)에 stdin을 전달합니다.

A 프로세스와 B 프로세스(A에서 호출)에 stdin을 전달합니다.

대화형 프로세스 A가 터미널에서 입력을 읽고 때때로 터미널에서 입력도 읽는 프로세스 B를 생성한다고 가정합니다. 예를 들어, A는 숫자를 읽고 B에게 제어권을 넘깁니다. B는 무엇이든 읽습니다.

편집하다:A와 B는 동시에 실행되지 않습니다. 특정 시나리오에서 A는 system()B를 호출하는 데 사용됩니다.

A가 되도록 표준 입력을 리디렉션하는 것이 가능합니까?그리고B는 표준 입력에서 읽습니까?

실험에 따르면 순진한

echo -e '123\nxyzzy' | A

123은 A가 읽어야 하지만 xyzzy는 B가 읽어야 하는데 아무런 효과가 없습니다.

답변1

여러 프로세스에 입력을 제공할 수 있습니다. 여러 프로세스가 동일한 파이프나 터미널에서 데이터를 읽는 경우 각 바이트는 프로세스 중 하나로 이동하며, 어느 프로세스가 특정 바이트를 먼저 읽는지 결정됩니다. 하나의 프로세스만 적극적으로 읽고 있을 때 입력을 받습니다. 여러 프로세스가 동시에 활발하게 읽고 있는 경우 어떤 프로세스가 입력을 받는지 예측할 수 없습니다.

당신은 갈등이 있습니다완충기. A를 포함한 대부분의 프로그램은 전체 입력 버퍼(보통 수백 또는 킬로바이트)를 한 번에 읽은 다음 처리를 시작할 때까지 자체 메모리에 저장합니다. 이는 한 번에 1바이트를 읽는 것보다 훨씬 빠릅니다. 하지만 이 경우 A는 B를 호출하기 전에 처리할 것보다 더 많은 것을 읽는다는 의미이므로 B가 시작될 때 B의 입력은 이미 A에 의해 소비되었습니다.

다른 소스에서 B를 읽을 수 있다면 이는 확실히 해결책입니다.

A가 실행되는 방식을 제어할 수 있다면 다음을 시도해 보십시오.stdbufGNU coreutils에서. 이는 라이브러리 호출에 연결되어 프로세스가 한 번에 1바이트를 읽도록 합니다. 이는 대부분의 프로그램에서 작동하지만 전부는 아닙니다. 정적으로 링크된 실행 파일에서는 작동하지 않으며 프로그램이 표준 라이브러리(stdio) 이외의 버퍼링 방법을 사용하는 경우 작동하지 않습니다.

… | stdbuf -i 1 A

또는 일반 파일에서 읽어 보십시오. A가 파이프나 터미널에서 입력을 읽으면 다시 넣을 수 없습니다. 그러나 일반 파일에서 읽을 경우 B를 호출하기 전에 읽기 위치를 되감을 수 있습니다. read예를 들어, 쉘 내장 기능이 작동하는 방식은 다음과 같습니다. 특정 프로그램 A가 이 작업을 수행한다는 보장은 없으며 실제로는 매우 일반적인 동작은 아니지만 만약 그렇다면 간단한 해결 방법입니다.

이것이 작동하지 않거나 A가 실행되는 방식을 제어할 수 없는 경우 B가 시작될 때까지 B에 대한 섹션이 나타나지 않도록 입력 시간을 조정해야 합니다. 이를 수행하는 방법은 B가 시작되었음을 감지하는 방법에 따라 다릅니다. 가능한 해결책 중 하나는 취약하지만 다음을 연기하는 것입니다.

{ echo 123; sleep 1; echo xyzzy; } | A

이는 A가 1초 이내에 B를 호출하는 경우에만 작동하며 이는 취약합니다. 보다 안정적인 솔루션은 A(또는 B)에서 생성된 출력을 감지하는 것입니다. 이게 문제 야예상되는해결하는 것을 목표로 합니다. 예를 들어 B가 다음과 같은 일종의 프롬프트를 표시하는 경우 B>:

#!/usr/bin/expect -f
spawn A
send "123\r"
expect "B>"
send "xyzzy\r"

답변2

이는 버퍼링 문제입니다. 프로세스 A는 stdio를 사용하여 stdin에서 상당한 양의 데이터를 읽으므로 B가 제어를 받을 때 B를 위해 의도된 부분은 사라집니다. 가능한 해결책은 다음과 같이 입력을 채우는 것입니다.

python -c 'print("123" + "\n"*4093 + "xyzzy\n")' | A

예상대로 작동합니다(실제 버퍼 크기 - 여기서는 4096 - 조정이 필요할 수 있음).

관련 정보