문제

나는 Stdin/stdout에서 읽고 쓰는 두 가지 (UNIX) 프로그램 A와 B가 있습니다.

첫 번째 문제는 A의 Stdout을 B의 Stdin에 연결하는 방법입니다. 그리고 aie의 stdin에 b의 stdout, a | b 그러나 양방향 파이프. 나는 이것을 해결할 수 있다고 생각한다 exec을 사용하여 리디렉션 그러나 나는 그것을 일할 수 없었다. 프로그램은 대화식이므로 임시 파일이 작동하지 않습니다.

두 번째 문제는 각 방향을 복제하고 로깅 프로그램을 통해 STDOUT를 통해 중복을 파이프하여 프로그램간에 전달되는 (텍스트 라인 기반) 트래픽을 볼 수 있다는 것입니다. 여기서 첫 번째 문제를 해결할 수 있다면 티> (...)로 도망 갈 수 있습니다.

이 두 가지 문제는 잘 알려진 솔루션을 가져야하는 것처럼 보이지만 아무것도 찾을 수 없습니다.

나는 posix 쉘 솔루션 또는 적어도 Cygwin에서 Bash에서 작동하는 것을 선호합니다.

귀하의 답변 덕분에 다음 솔루션을 생각해 냈습니다. A/B 명령은 NC를 사용하여 두 개의 포트를 듣습니다. 로깅 프로그램은 SED를 사용합니다 (Unfufered Processing의 경우 -U와 함께).

bash-3.2$ fifodir=$(mktemp -d)
bash-3.2$ mkfifo "$fifodir/echoAtoB"
bash-3.2$ mkfifo "$fifodir/echoBtoA"
bash-3.2$ sed -u 's/^/A->B: /' "$fifodir/echoAtoB" &
bash-3.2$ sed -u 's/^/B->A: /' "$fifodir/echoBtoA" &
bash-3.2$ mkfifo "$fifodir/loopback"
bash-3.2$ nc -l -p 47002 < "$fifodir/loopback" \
          | tee "$fifodir/echoAtoB" \
          | nc -l -p 47001 \
          | tee "$fifodir/echoBtoA" > "$fifodir/loopback"

이는 포트 47001 및 47002에 연결하고 모든 트래픽을 표준 출력으로 반향합니다.

쉘 2에서 :

bash-3.2$ nc localhost 47001

쉘 3에서 :

bash-3.2$ nc localhost 47002

이제 쉘 2에 입력 된 라인은 쉘 3에 기록되며 그 반대도 마찬가지이며 트래픽은 다음과 같은 것과 같은 쉘 1에 로그온했습니다.

B->A: input to port 47001
A->B: input to port 47002

상기는 Cygwin에서 테스트되었습니다

업데이트 : 위의 스크립트는 며칠 후 작동 중지되었습니다 (!). 분명히 교착 상태가 될 수 있습니다. 답의 일부 제안 중 일부는 더 신뢰할 수 있습니다.

도움이 되었습니까?

다른 팁

명명 된 파이프는 어떻습니까?

# mkfifo foo
# A < foo | B > foo
# rm foo

두 번째 부분의 경우 Tee가 정답이라고 생각합니다. 그래서 그것은 다음과 같습니다.

# A < foo | tee logfile | B > foo

당신은 아마도 이름이 지정된 파이프로 도망 갈 수 있습니다.

mkfifo pipe
gawk '$1' < pipe | gawk '$1' > pipe

당신이 사용할 수있는 예상하다.

기대는 Telnet, FTP, Passwd, FSCK, Rlogin, Tip 등과 같은 대화식 응용 프로그램을 자동화하는 도구입니다.

다음 코드를 사용할 수 있습니다 ( 기대를 탐구합니다 Book) 시작점 - Proc1의 출력을 Proc2의 입력에 연결하고 요청한대로 그 반대도 마찬가지입니다.

#!/usr/bin/expect -f
spawn proc1
set proc1 $spawn_id
spawn proc2
interact -u $proc1

나는 이것에 많은 시간을 보냈고, 포기했고, 마지막으로 KSH (Korn Shell)를 사용하기로 결정했습니다.

cmd1 |& cmd2 >&p <&p

어디 |& 공동 프로세스를 시작하는 (파이프) 연산자입니다. &p 해당 공동 프로세스의 파일 디스크립터입니다.

나는 한 시점 에서이 문제를 겪었고이 간단한 C 프로그램을 함께 던졌습니다.

#include <stdio.h>
#include <unistd.h>

#define PERROR_AND_DIE(_x_) {perror(_x_); _exit(1);}

int main(int argc, char **argv) {
    int fd0[2];
    int fd1[2];


    if ( argc != 3 ) {
        fprintf(stdout, "Usage %s: \"[command 1]\" \"[command 2]\"\n", argv[0]);
        _exit(1);
    }

    if ( pipe(fd0) || pipe(fd1) ) PERROR_AND_DIE("pipe")

    pid_t id = fork();
    if ( id == -1 ) PERROR_AND_DIE("fork");

    if ( id ) {
        if ( -1 == close(0) )  PERROR_AND_DIE("P1: close 0");
        if ( -1 == dup2(fd0[0], 0) ) PERROR_AND_DIE("P1: dup 0"); //Read my STDIN from this pipe

        if ( -1 == close(1) )  PERROR_AND_DIE("P1: close 1");
        if ( -1 == dup2(fd1[1], 1) ) PERROR_AND_DIE("P1: dup 1"); //Write my STDOUT here
        execl("/bin/sh", "/bin/sh", "-c", argv[1], NULL);
        PERROR_AND_DIE("P1: exec")
    }

    if ( -1 == close(0) )  PERROR_AND_DIE("P2: close 0");
    if ( -1 == dup2(fd1[0], 0) ) PERROR_AND_DIE("P2: dup 0");

    if ( -1 == close(1) )  PERROR_AND_DIE("P2: close 1");
    if ( -1 == dup2(fd0[1], 1) ) PERROR_AND_DIE("P2: dup 1");


    execl("/bin/sh", "/bin/sh", "-c", argv[2], NULL);
    PERROR_AND_DIE("P2: exec")
}

이 질문은 비슷합니다 하나 나는 전에 물었다. 다른 사람들이 제안한 솔루션은 이름이 지정된 파이프를 사용하는 것이었지만 Cygwin에는 파이프가 없다고 생각합니다. 현재 나는 고집하고있다 내 자신의 (a) 솔루션, 그러나 필요합니다 /dev/fd/0 아마 당신도 가지고 있지 않을 것입니다.

나는 통과 명령 라인-스트링스 측면을 정말로 좋아하지 않지만 twinpipe (Jeebee가 언급했습니다.139495)), Cygwin에서 유일한 옵션 일 수 있습니다.

"Coproc"을 제안합니다 :

#! /bin/bash
# initiator needs argument

if [ $# -gt 0 ]; then
  a=$1
  echo "Question $a"
else
  read a
fi

if [ $# -gt 0 ]; then
  read a
  echo "$a" >&2
else
  echo "Answer to $a is ..."
fi

exit 0

그런 다음이 세션을 참조하십시오.

$ coproc ./dialog
$ ./dialog  test  < /dev/fd/${COPROC[0]}  > /dev/fd/${COPROC[1]}
Answer to Question test is ...
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top