That inetd
service or yours is probably waiting for EOF before exiting (and then closing the connection).
To do that, you'd need the client to shutdown the sending side of the socket while still keeping the receive side open. That's what nc
does when it detects EOF on its stdin.
The /dev/tcp/host/port
virtual interface of bash
(copied from ksh) doesn't allow that. Even zsh
's ztcp
more flexible alternative doesn't have the ability to asymmetrically shutting down connections.
You could rely on a timeout instead, but that would be unreliable. So best it to keep relying on dedicated utilities like nc
or socat
(possibly with a coproc to have a similar interface), or use a programming language with a proper network API (with an interface to shutdown()
).
The 0x04 character (^D
) only means EOF for terminal devices when the line discipline is in icanon
mode (implements a crude line editor). So for that to work you'd have to insert a pseudo-terminal in between the socket created by xinetd
and your service. For instance, by starting it with:
socat - exec:'your-service',pty,raw,icanon,echo=0,discard=,lnext=,werase=,kill=,start=,stop=,rprnt=,erase=,fdout=3
instead of
your-service
Then you'd need to send:
printf 'text\n\4' >&7
Or:
printf 'text\4\4' >&7
for your-service to see the end of input.
Because of that line editor, your-service
will only see input when you send newline or ^D
characters (we've disabled all the other editing characters like werase
, erase
, kill
above and the ^C
, ^Z
... handling is also disabled as part of raw
).
So you might as well insert an input pre-processor instead that quits upon that 0x4 character like:
awk -v RS='\4' -v ORS= '{print; exit}' | your-service
(note that that awk
can't be mawk
as mawk
insists in not processing its input as long as it's not received a full buffer or eof).