Como finalizar uma conexão TCP estabelecida pelo próprio bash?

17

Eu usei exec 3<>/dev/tcp/192.168.0.101/6435para estabelecer uma conexão TCP com 192.168.0.101:6435. E recebi e enviei algumas mensagens com o pipecomando

Agora, desejo encerrar a conexão TCP. Mas, com ss -anpetposso ver que o próprio bash mantém essa conexão, sem bifurcar um processo filho.

Tentei enviar os sinais 9 e 15 para o processo do bash, mas como você sabe, o bash não pode se matar.

Então, posso encerrar a conexão TCP que estabeleci sem encerrar os pts que estou usando (nem matá-la pelo root nem enviar Ctrl + D)?

TJM
fonte
Você poderia obter outra concha e matar bashcom essa concha?
trysis
3
bashcertamente pode se matar - embora não seja exatamente isso que você queira fazer aqui!
psmears
@TJM para tornar essa pergunta fascinante mais útil para outras pessoas, você poderia elaborar o pipecomando que está usando e que não consigo encontrar no meu sistema? De qual pacote pipevem? Quais parâmetros (exemplo) você pode passar para enviar / receber dados pela /dev/tcp/...conexão? Obrigado.
Arielf 13/06/16
@arielf Normalmente, sou iniciante em ciência da computação e encontrei esse tipo de uso em um script bash shell chamado sedbot, você pode encontrá-lo no Github. Sim, não consigo encontrar nenhum arquivo /dev/tcp, nem mesmo consigo encontrar /dev/tcp. Mas, parece um uso especial com o qual você pode enviar / receber dados pipee esse tipo de arquivo. Diz-se que use /dev/tcp/ip/portpara conexões tcp e /dev/udp/ip/portpara pacotes udp. Como meu inglês não é muito bom, não sei como explicá-lo adequadamente. Sinta-se à vontade para editar a pergunta e postar uma resposta.
TJM 14/06
@TJM thanks. A pergunta era sobre o pipecomando que você mencionou. Eu olhei https://github.com/clsr/sedbot/blob/master/sedbot.bash. Não há pipecomando lá. Ele define duas funções: readmsge sendmsgpara ler / gravar de / para a conexão, respectivamente. readmsgusa IFS= read -r -u 3 -t "$READ_TIMEOUT" linepara ler do descritor de arquivo 3 na variável linee sendmsgusa echo "$(date +%s.%N) >>> $line" >&4para escrever no descritor de arquivo 4. De qualquer forma, isso esclarece o método completo. A pipemenção "comando" ainda permanece um mistério para os leitores.
Arielf

Respostas:

18

Esse comando abriu a conexão no descritor de arquivo 3. Portanto, para fechar a conexão, você precisa fechar o descritor de arquivo 3. Para fazer isso:

exec 3<&-
Patrick
fonte
1
Isso fará uma shutdown(3)chamada adequada ou apenas close(2)o descritor de arquivo?
Kevin
Faz um close, mas shutdownnão é mais apropriado que fechar. shutdownO único uso real é quando você deseja fechar apenas um lado de um soquete duplex.
Patrick
4
Um shutdownenvia um FIN, enquanto um closeenvia um RST. Essas são coisas materialmente diferentes.
Kevin
2
O @Kevin RST é causado pelo fechamento do soquete sem ler todos os dados dele primeiro. Se você ler até o final dos dados e depois fechar, o fechamento enviará um FIN.
kasperd
@kasperd: Na API de soquete UNIX, a única maneira de saber se há dados pendentes é tentar ler de um soquete não-bloqueante ou chamar algo do tipo select(), e eu não acredito que o bash ofereça uma opção.
Kevin