Bash TCP 리디렉션 전송이 종료됩니다.

Bash TCP 리디렉션 전송이 종료됩니다.

나는 tcp 소켓에서 문자열을 읽고 인코딩된 뷰를 출력하는 xinetd를 사용하여 간단한 웹 서비스를 만들었습니다. 원시 바이너리(qrencode)는 표준 입력만 읽습니다.

netcatas와 함께 사용하면 잘 작동합니다.echo string | nc <ip> <port>

하지만 bash tcp 리디렉션을 통해 사용하려고 하면 응답하지 않습니다.

exec 7<>/dev/tcp/<ip>/<port>
echo string >&7
cat <&7

영원히 기다립니다. 나는 이 fd에 \004, cat /dev/null을 에코하려고 시도했지만 성공하지 못했습니다. 어떻게 작동하게 할 수 있나요?

답변1

서비스 inetd또는 귀하의 서비스가 EOF를 기다리고 있을 수 있으며, 그런 다음 종료합니다(그런 다음 연결을 닫습니다).

이렇게 하려면 클라이언트가 소켓의 송신측을 닫고 수신측은 계속 열어두어야 합니다. 이것이 nc표준 입력에서 EOF를 감지할 때 수행되는 작업입니다.

/dev/tcp/host/port가상 인터페이스( bashksh에서 복사됨)는 이를 허용하지 않습니다. zsh보다 유연한 대안 이라도 ztcp연결을 비대칭적으로 닫을 수는 없습니다.

대신 시간 초과를 사용할 수도 있지만 이는 신뢰할 수 없습니다. 따라서 nc또는 같은 전용 유틸리티를 계속 사용 socat하거나(유사한 인터페이스를 갖기 위해 coproc 사용) 적절한 네트워크 API(coproc에 대한 인터페이스 포함 shutdown()) 가 있는 프로그래밍 언어를 사용하는 것이 좋습니다 .

^D선 규칙이 icanon모드(대략적인 선 편집기 구현)에 있을 때 0x04 문자( )는 단순히 최종 장치의 EOF를 나타냅니다. 따라서 이것이 작동하려면 xinetd서비스에서 생성된 소켓 사이에 의사 터미널을 삽입해야 합니다. 예를 들어 다음과 같이 시작합니다.

socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3

바꾸다

your-service

그런 다음 다음을 보내야 합니다.

printf 'text\n\4' >&7

또는:

printf 'text\4\4' >&7

서비스에서 입력의 끝을 볼 수 있습니다.

행 편집기로 인해 your-service개행 또는 문자를 전송하는 경우에만 입력을 볼 수 있습니다 ^D( 위의 , , werase, erase... 처리 도 의 일부로 비활성화됨 ).kill^C^Zraw

따라서 0x4 문자에서 종료하는 대신 입력 전처리기를 삽입할 수도 있습니다. 예를 들면 다음과 같습니다.

awk -v RS='\4' -v ORS= '{print; exit}' | your-service

(전체 버퍼 또는 eof가 수신되지 않는 한 입력을 처리하지 않을 awk수 없습니다 .)mawkmawk

답변2

서비스가 설정된 TCP 세션을 닫지 않으면 클라이언트 연결을 중지하는 것 외에는 다른 방법이 없는 것 같습니다. 예를 들어 timeout 명령을 사용합니다.

timeout 1 cat <&7

echoing \004, cat /dev/null또한 시도하는 다른 명령( )은 다른 셸에서 실행하기 때문에 실패할 가능성이 높습니다. 파일 설명자 7은 첫 번째 쉘을 실행하는 쉘에 연결되어 있으므로 exec 7<>/dev/tcp/<ip>/<port>첫 번째 쉘 내에서만 상호 작용할 수 있습니다.

인용하다

관련 정보