nc -l em segundo plano fecha imediatamente (nc -l 1234 &)

3

Quando eu coloco isso

nc -l 12345 >nc_out

em um shell script, execute-o e então conecte-se a partir de outro shell usando telnet, ele permite que eu digite algum texto e termine em nc_out .

Mas se eu iniciar o nc em segundo plano (quero iniciar o telnet a partir do mesmo script mais tarde):

nc -l 12345 >nc_out &

a conexão é fechada imediatamente:

# telnet localhost 12345
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host
#

deixando o arquivo nc_out vazio.

Por que isso? Como posso fazer o nc aceitar conexão normalmente?

Notas:

  • No RHEL e no Fedora, nc e nmap-ncat se comportam dessa maneira, mas O nc-tradicional do Debian aceita a conexão e me deixa salvar os dados para nc_out.

  • Não importa se eu chamo o telnet do mesmo script ou diferente (SSH), o comportamento é o mesmo

  • Eu também executei o comando com strace como @Hauke Laging sugeriu e postou a saída de strace no Pastebin

por Alois Mahdal 01.07.2014 / 17:58

1 resposta

3

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 &'
    
por 16.10.2014 / 17:54