Os comandos em segundo plano que são executados em shells não interativos com o controle de tarefa desativado (como é o caso em scripts de shell) obtêm seu stdin
implicitamente redirecionado de /dev/null
.
sh -c 'nc -l 12345 1>nc_out & lsof -p $!'
De 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.
Quando o cliente telnet
estabelece sua conexão com localhost
e o comando nc
já em execução via porta 12345
, o comando nc
em segundo plano parece detectar EOF em seu status e inicia seu processo de encerramento porque é leitura forçada de / dev / null. Um valor de retorno de zero do comando read
( man 2 read
) indica o fim do arquivo.
# strace output (from http://pastebin.com/YZHW31ef)
14:32:26 read(0, "", 2048) = 0
14:32:26 shutdown(4, 1 /* send */) = 0
Aqui estão algumas soluções para manter telnet
em execução e se comunicando com 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 &'