Note that this answers an earlier version of the question where the command was meant to be a server.
No in bash
(and ksh
where that feature comes from), /dev/tcp/host/port
are virtual files that are meant to be for client TCP connections.
The shell will connect to host:port, and make that connected socket the fd that is the subject of the redirection. With <
or <>
, it's fd 0 (stdin), with >
, >>
it's fd 1, but the operators make no difference. In particular it's not because you use <
that the shell shuts down the sending direction of the socket; stdin will still be connected to a socket which you can both read from and write to.
If you want to listen (be a server) and accept one or more connections, you can't use /dev/tcp/host/port
.
You'd need to use a dedicated tool like socat
or nc
, or a shell with builtin support for that like zsh
with its ztcp
builtin.
timeout 60 socat -u tcp-listen:12345,reuseaddr,bind=127.0.0.1,fork - | wc -c
Will listen on port 12345 on the loopback IPv4 address and accept incoming connections in child processes, write what is received on stdout (here piped to wc
).
There are several implementations of a tool called nc
or netcat
with which you can generally do the same with:
timeout 60 nc -l 127.0.0.1 12345 | wc -c
Note that it run that command for 60 seconds. That includes the time while it's sitting doing nothing waiting for incoming connections.
If you want the timer to start upon the incoming connection, you could do instead:
socat -u tcp-listen:12345,reuseaddr,bind=127.0.0.1 'EXEC:timeout 60 cat' | wc -c
Here accepting only one TCP connection (no fork
) which is then piped to timeout 60 cat
.
Just to clarify what I think you may be asking in the subject, when you do:
cmd1 | cmd2
It's not cmd1
running and when it's finished, the data is sent to cmd2
. Instead cmd1
and cmd2
are started concurrently (they run in parallel) with a pipe in between them (cmd1
's stdout is the writing end of the pipe and cmd2's stdin is the reading end).
In:
timeout 60 nc -l 127.0.0.1 12345 | wc -c
You've got timeout
and wc
running in parallel. timeout
starts another process in which it executes nc
(which will share the same stdout).
After 60 seconds, timeout
will kill that other process. At that point nc
will exit, but it will have written what it has received from the socket to the pipe (nc
or socat
don't buffer their output), so even if wc
hasn't read it yet, it will be accounted for as wc
will keep reading until the pipe is empty.
(timeout 60 nc ...) | wc –c
Would be the same. (code)
is to start a subshell (a child shell process (in shells other than ksh93) that is evaluating the code
). But here, since it's part of pipeline, that code has to be in a subshell already (different parts of a pipeline have to run in different processes as they run concurrently).