하위 프로세스의 파일 설명자(fd/0)에 쓰기

하위 프로세스의 파일 설명자(fd/0)에 쓰기

CentOS 7 샌드박스에서 파일 설명자를 사용하고 있습니다. 이 작업을 수행하는 동안 흥미로운 상황을 발견했습니다. 간단한 PHP 스크립트가 있다고 가정해 보겠습니다.

$step = 4 * 1024;

echo "php started\n";
while (!\feof(\STDIN)) {
    \fwrite(\STDOUT, 'read stdin part: '.\fread(\STDIN, $step)."\n");
}
echo "php finished\n";

bash 스크립트의 하위 프로세스로 백그라운드에서 실행하고 다음과 같은 표준 입력에 전달하고 싶습니다.

php read.php &
phpProcId=$(ps axw -o pid,command | grep 'read' | head -1 | sed -r 's|^\s*([0-9]+)[^0-9]+.*$|\1|g')
echo "phpProcId: $phpProcId"
echo -e "test1\ntest2" >> /proc/$phpProcId/fd/0

그러나 쉘 출력은 다음과 같습니다.

$ sh box.sh
phpProcId: 2818
$ php started
read stdin part: 
php finished

Bash 스크립트가 PHP 스크립트 이전에 작업을 완료하고 해당 데이터를 PHP 하위 프로세스에 제때 전달하지 못한 것 같습니다. fd/0에 기록하여 PHP 하위 프로세스에 데이터를 전달하려면 어떻게 해야 합니까? 나는 mkfifo에 대해 알고 있으며 이 경우 의도적으로 사용하고 싶지 않습니다.

답변1

나는 PHP를 전혀 이해하지 못합니다. 이 답변은 쉘에 관한 것입니다.

  1. 작업 제어 […]가 비활성화된 경우 명시적인 리디렉션이 수행되기 전에 비동기 목록의 표준 입력은 와 동일한 이름을 가진 파일에 할당된 것처럼 처리됩니다 /dev/null. […]

    (원천)

    sh셸과 같은 스크립트를 실행하면 기본적으로 작업 제어가 비활성화됩니다.

    이는 php read.php &일부 fifo에서 읽지 않으며 전체 쉘 스크립트와 stdin을 공유하지도 않음을 의미합니다. 읽고 있는 파일( /proc/…/fd/0또는 다른 형식) 을 올바르게 식별하더라도 해당 파일에 쓰는 것은 /dev/nullfifo에 쓰는 것이 아니라 write 와 같습니다.

    만약 너라면진짜원하는 것을 인쇄 /proc/…/fd/0하고 얻으려면 like가 아닌 fifo처럼 동작하는 것을 가리켜야 하므로 /dev/null합리적인 mkfifo기본 선택입니다.

  2. 필요하다고 생각한다면 지금 사용하고 있는 이 기기보다 더 좋은 것이 phpProcId있을 수도 있습니다 . 현재 셸에서 실행된 가장 최근 백그라운드 명령의 10진수 프로세스 ID로 확장됩니다. 하지만 어쩌면 필요하지 않을 수도 있습니다. 왜냐하면...phpProcId=$!phpProcId=$(ps …)$!

  3. Bash에서는 프로세스에 인쇄할 파일 설명자를 만들 수 있습니다. 아래 예에서 프로세스는 다음과 같습니다 cat -n.

    exec 3> >(cat -n)
    # ...
    echo -e "test1\ntest2" >&3
    exec 3>&-
    

    이 명명되지 않은 fifo의 쓰기 부분은 우리가 닫힐 때 열리고 exec설명자는 닫힐 때 열립니다 exec 3>&-(그것 없이: 쉘이 종료될 때). 일부 하위 프로세스가 해당 설명자를 상속하고 열린 상태로 유지하지 않는 한, cat연결된 후 표준 입력이 더 이상 어떤 것에도 연결되지 않기 때문에 결국 종료됩니다. 그렇지 않더라도 echo우리는 cat그만둘 것이다.

    cat스크립트가 종료된 후 인쇄 프롬프트 전후에 대화형 셸의 출력이 표시될 수 있습니다.

  4. >(…)정상적인 형태로 작업할 수 없습니다 sh. 당신이 태그했어요그러나 sh box.sh필요한 경우 사용하십시오 bash(shebang 사용을 고려하십시오) >(…).

관련 정보