백그라운드에서 실행 중인 프로세스에 명령을 파이프하는 방법은 무엇입니까?

백그라운드에서 실행 중인 프로세스에 명령을 파이프하는 방법은 무엇입니까?

이것은 백그라운드에서 실행되고 명령을 기다리는 루프 프로그램입니다.

#include <iostream>

using namespace std;

char buffer[256];

int main(int argc, char *argv[])
{
    while(true){
     fgets(buffer, 255, stdin);
     buffer[255] = 0;
     if(buffer[0] != '\0'){
        cout << buffer;
        buffer[0] = '\0';
     } 
    }
 return 0;
}

나는 그것을 실행합니다 :

myLoop &

이제 파이프를 통해 이 프로세스에 명령을 어떻게 보내나요?

답변1

나는 이것이 "실제" 파이프라인에서는 불가능하다고 생각합니다.

man mkfifo대신 FIFO(이름이 지정된 파이프, 참고자료 참조 ) 또는 (더 우아하지만 더 복잡한) Unix 소켓(AF_UNIX)을 사용할 수 있습니다 .

./background-proc </path/to/fifo &
cat >/path/to/fifo
# typing commands into cat

저는 개발자가 아니므로 소켓과의 유일한 관계는 입니다 socat. 하지만 시작에는 도움이 될 수 있습니다.

프로그램과 통신하려면 "서버"가 필요합니다. 이러한 파이프라인은 백그라운드에서 시작됩니다.

socat UNIX-LISTEN:/tmp/sockettest,fork STDOUT | sed 's/./&_/g'

이것은 sed단지 테스트용입니다.

그런 다음 하나 이상의 시작

socat STDIN UNIX-CONNECT:/tmp/sockettest

백그라운드 프로그램에 대한 명령을 생성하는 프로그램이 있는 경우 여기에서도 파이프를 사용할 수 있습니다.

cmd_prog | socat STDIN UNIX-CONNECT:/tmp/sockettest

forkFIFO에 비해 장점은 (서버 측 옵션을 사용하여) 클라이언트 연결을 끊었다가 다시 연결할 수 있다는 것입니다. FIFO를 사용하면 수신 측을 계속 실행하려면 몇 가지 트릭이 필요합니다.

while true; do cat /path/to/fifo; done | background_prog

답변2

백그라운드에서 명령을 시작하고 파일 설명자가 데이터를 파이프하도록 하려는 경우.

zsh또는 를 사용하면 bash리디렉션을 사용하여 교체를 처리할 수 있습니다.

exec 3> >(cmd)

그런 다음 출력을 보냅니다.

echo something >&3

그리고 파일 문자의 끝을 알리는 데 사용합니다 exec 3>&-.

계속해서 zsh및 을 사용하여 bash다음을 수행할 수도 있습니다.

{ coproc cmd >&3 3>&-; } >&3

이는 cmd두 개의 파이프(입력용 파이프와 출력용 파이프)로 프로세스를 시작하는 코프로세스로 시작됩니다. 그러나 여기서는 입력용으로 하나만 필요하므로 cmd나머지 쉘 출력에 대해 stdout을 표준으로 되돌립니다.

출력 보내기:

echo something >&p # with zsh
echo something >&"${COPROC[1]}" # with bash

통과하면 yash사용할 수 있습니다프로세스 리디렉션:

exec 3>(cmd)

Bourne과 유사한 쉘을 사용하면 언제든지 다음을 수행할 수 있습니다.

{ {
  echo something >&3
  echo whatever
  ...
} 3>&1 >&4 4>&- | cmd; } 4>&1

cmd이는 출력을 보내는 백그라운드에서 명령을 시작하고 실행하는 것과 정확히 동일하지 않습니다. cmd해당 명령은 하위 쉘에서 실행되고 대화형 쉘의 경우 cmd전경에서도 실행되기 때문입니다(예: Ctrl+C의 영향을 받음). 그보다 기본적으로 기능적으로 동일합니다.

답변3

일반적으로 프로세스에서 열린 파일과 프로세스가 시작된 후에는 프로세스 외부에서 해당 파일이 가리키는 위치를 변경할 수 없습니다. 인터페이스 및 도구 디버깅에는 예외가 있습니다.렙티이는 제한된 방식으로 수행될 수 있습니다.

프로그램을 시작하면

myLoop &

표준 입력은 이미 터미널에 연결되어 있으며(다른 곳으로 리디렉션하지 않기 때문에) 파이프로 변경되지 않습니다.

당신은 또한 볼 수 있습니다분리된 프로세스에 터미널을 연결하는 방법은 무엇입니까?

관련 정보