명명된 파이프를 netcat의 데이터 소스로 사용

명명된 파이프를 netcat의 데이터 소스로 사용

명명된 파이프에서 데이터를 읽는 TCP 서버로 netcat을 사용하고 싶습니다. 이를 위해 나는 다음을 수행했습니다.

1단계. 파이프라인을 생성하여 소스 서버로 사용

mkfifo /tmp/all.pipe
nc -k -l 8080 < /tmp/all.pipe

2단계. 지속적으로 데이터를 읽는 클라이언트를 만듭니다.

while true; do
    sleep 1;
    echo "Check connection";
    while IFS= read -r line; do
        printf "$line";
    done < /dev/tcp/localhost/8080;
done

3단계. 파이프에 일부 데이터 쓰기:

echo "hello" > /tmp/all.pipe

이 3단계를 실행한 후 클라이언트의 출력은 다음과 같습니다.

...
bash: connect: Connection refused
bash: /dev/tcp/localhost/8080: Connection refused
Check connection
bash: connect: Connection refused
bash: /dev/tcp/localhost/8080: Connection refused
Check connection
hello

그러나 3단계를 다시 수행하면 출력이 변경되지 않습니다. 연결이 여전히 활성화되어 있지만 새 데이터가 파이프에서 nc로 전달된 다음 클라이언트로 전달되지 않기 때문에 이런 일이 발생하는 것 같습니다. 왜? 그것을 달성하기 위해 무엇을 할 수 있습니까?

답변1

위에:

nc -k -l 8080 < /tmp/all.pipe

쉘이 열려고 시도 /tmp/all.pipe하지만 아직 쓰기 위해 명명된 파이프를 연 프로세스가 없기 때문에 정지됩니다.

nc아직 시작되지 않았 으므로 다음과 bash같은 이유가 설명됩니다.연결이 거부되었습니다.거기에 연결하려고 할 때.

당신이 할 때

echo "hello" > /tmp/all.pipe

그런 다음 첫 번째 명령이 잠금 해제됩니다. 이제 파이프가 인스턴스화되었습니다.

그런 다음 거기에 echo쓰고 hello\n종료합니다. 이 시점에서 파이프의 쓰기 끝이 닫히고 nc파일 끝이 표준 입력에 표시됩니다. cat대신 을 사용하면 nc종료 cat됩니다.

그러나 의 경우 nc표준 출력은 이 시점에서 여전히 터미널에 도착하고 TCP 연결은 여전히 ​​활성 상태이므로 한쪽 끝이 입력 끝에 도달하더라도 계속됩니다. 예를 들어 bash해당 소켓에 무언가를 보내면 stdout에 나타납니다.nc

두 번째 작업을 수행할 때 파이프의 fd가 아직 닫히지 않았기 echo something > /tmp/all.pipe때문에 (적어도 Ubuntu, YMMV 패키지의 경우 ) 다시 온라인 상태가 되는 동일한 파이프를 통과하지만 포기했습니다. 나중에 읽으면 더 일찍 eof에 도달했습니다.ncncnetcat-openbsdnc

여기서 가장 간단한 것은 파이프의 입력을 읽기+쓰기 모드로 열어서 nc즉시 인스턴스화되고 nc수명이 있는 동안 항상 유지되도록 하는 것입니다.

이렇게 하려면 명령줄을 <다음으로 바꾸십시오.<>nc

nc -k -l 8080 <> /tmp/all.pipe

또한 첫 번째 매개변수 printf는 형식이므로 거기에 변수가 있어서는 안 됩니다. 줄 구분 기호 없이 입력 줄을 인쇄하려면 다음을 사용하세요.

printf %s "$line"

관련 정보