명명된 파이프에서 데이터를 읽는 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에 도달했습니다.nc
nc
netcat-openbsd
nc
여기서 가장 간단한 것은 파이프의 입력을 읽기+쓰기 모드로 열어서 nc
즉시 인스턴스화되고 nc
수명이 있는 동안 항상 유지되도록 하는 것입니다.
이렇게 하려면 명령줄을 <
다음으로 바꾸십시오.<>
nc
nc -k -l 8080 <> /tmp/all.pipe
또한 첫 번째 매개변수 printf
는 형식이므로 거기에 변수가 있어서는 안 됩니다. 줄 구분 기호 없이 입력 줄을 인쇄하려면 다음을 사용하세요.
printf %s "$line"