nc -l in background closes immediately (nc -l 1234 &)
Backgrounded commands that are executed in non-interactive shells with job control disabled (as it is the case in shell scripts) get their stdin
implicitly redirected from /dev/null
.
sh -c 'nc -l 12345 1>nc_out & lsof -p $!'
From POSIX.1-2008:
2. Shell Command Language
[...]
Asynchronous Lists
If a command is terminated by the control operator ( '&' ), the shell shall execute the command asynchronously in a subshell. This means that the shell shall not wait for the command to finish before executing the next command.
The format for running a command in the background is:
command1 & [command2 & ... ]
The standard input for an asynchronous list, before any explicit redirections are performed, shall be considered to be assigned to a file that has the same properties as /dev/null. If it is an interactive shell, this need not happen. In all cases, explicit redirection of standard input shall override this activity.
When the telnet
client establishes its connection to localhost
and the already running nc
command via port 12345
, the backgrounded nc
command seems to detect EOF on its stdin and starts its shutdown process because it is forced reading from /dev/null. A return value of zero of the read
command (man 2 read
) indicates end of file.
# strace output (from http://pastebin.com/YZHW31ef)
14:32:26 read(0, "", 2048) = 0
14:32:26 shutdown(4, 1 /* send */) = 0
Here are some solutions to keep telnet
running and communicating with nc
:
sh -c 'nc -l 12345 0<&0 1>nc_out &'
sh -c 'nc -l 12345 0<&- 1>nc_out &'
sh -c 'tail -f /dev/null | nc -l 12345 1>nc_out &'
sh -c 'rm -f fifo; mkfifo fifo; exec 3<>fifo; nc -l 12345 0<fifo 1>nc_out &'