P
기능을 제공하기 전에 "Hello"를 받고 "Why?"를 출력하는 프로그램이 있습니다 . 이 기능은 "Hello"로 대화를 시작하는 것이 일반적인 예의라는 것을 모르는 다른 프로그램에서 사용됩니다. 그래서 다음과 같이 작동하는 래퍼를 작성하고 싶습니다 P
(zsh 구문).
coproc P
print -p Hello # Send Hello to P
read -pr line # Read what P has to say
[[ "$line" = "Why?" ]] && Replace current process with the coprocess.
echo Could not get P's attention.
섹션(예: )에 사용되거나 cat
불필요한 버퍼링이 발생할 수 있습니다. 내 옵션은 무엇입니까?dd
Replace...
cat <&p &; exec cat >&p
답변1
당신이 말하는 문제는 실제로 교체에 관한 것이 아닙니다.프로세스, 그러나 기존 프로세스를 대체함개울. 목표는 프로세스와 어느 정도 상호 작용한 다음 해당 입력/출력을 연결된 다른 스트림 쌍에 전달하는 것입니다.
이 작업을 직접 수행할 수 있는 방법은 없습니다(적어도 셸에서는, 프로세스 내부에서는 호출이 dup2
작동할 수 있습니다). 스트림을 연결해야 합니다. 즉:
( echo Hello ; cat ) | P | ( read ; cat )
귀하의 예에서와 같이 사용하면 coproc
효과가 있습니다. 이 명령은 파일 설명자를 배열에 저장하고 나중에 리디렉션에 사용할 수 있다는 점에 유의하세요.
P가 연결된 입력/출력 스트림을 검사하고 그에 따라 버퍼링 결정을 내리지 않는 한 이로 인해 추가 버퍼링이 발생해서는 안 됩니다(적어도 GNU cat의 경우). 예를 들어, C 표준 라이브러리는 파일에 연결된 경우 /에서 버퍼링을 활성화 stdout
하지만 터미널에 연결된 경우에만 라인 버퍼링을 수행합니다.stderr
답변2
버퍼링을 피하기 위해 Perl을 사용하여 다음 코드를 테스트할 수 있습니다. 이것이 효과가 있는지 시도해 보십시오.
P의 예시 버전
$ cat /tmp/P
#!/bin/bash
read input
if [[ $input = "Hello" ]]
then
echo "Why?"
else
exit 1
fi
echo "Got Hello from client, working ..."
sleep 10
echo "Need to read some input"
read x
echo "Got: $x"
포장 프로그램
$ cat /tmp/wrapper
#!/usr/bin/zsh
coproc /tmp/P
print -p Hello # Send Hello to P
read -pr line # Read what P has to say
if [[ "$line" = "Why?" ]]; then
perl -e '$|=1;print $_ while(<>);' <& p &
perl -e '$|=1;print $_ while(<>);' >& p
else
echo "Could not get P's attention."
fi
테스트 실행
$ /tmp/wrapper Got Hello from client, working ... Need to read some input hi there P! <== Typed in at teminal Got: hi there P!