Jak zakończyć połączenie TCP ustanowione przez samą bash?

17

Użyłem exec 3<>/dev/tcp/192.168.0.101/6435do ustanowienia połączenia TCP z 192.168.0.101:6435. I otrzymałem, a także wysłałem kilka wiadomości z pipepoleceniem.

Teraz chcę zakończyć połączenie TCP. Ale ss -anpetwidzę, że sama bash utrzymuje to połączenie, bez rozwodzenia procesu potomnego.

Próbowałem wysłać sygnał 9 i 15 do procesu bash, ale jak wiadomo, bash nie może się zabić.

Czy mogę zatem zakończyć nawiązane połączenie TCP bez przerywania używanych przeze mnie pkt. (Nie zabijając go przez root, ani wysyłając Ctrl + D)?

TJM
źródło
Czy możesz zdobyć kolejną powłokę i zabić bashtą skorupą?
trysis
3
bashz pewnością może się zabić - choć tak naprawdę nie chcesz tego tutaj robić!
psmears
@TJM, aby to fascynujące pytanie było bardziej przydatne dla innych, czy mógłbyś rozwinąć pipepolecenie, którego używasz, a którego nie mogę znaleźć w moim systemie? Z której paczki pipepochodzi? Jakie (przykładowe) parametry możesz mu przekazać, aby wysłać / odebrać dane przez /dev/tcp/...połączenie? Dzięki.
arielf
@arielf Zazwyczaj jestem początkującym informatykiem i znalazłem takie zastosowanie ze skryptu powłoki bash o nazwie sedbot, który można znaleźć na Github. Tak, nie mogę znaleźć żadnych plików /dev/tcp, nawet nie mogę się znaleźć /dev/tcp. Ale wydaje się, że jest to specjalne zastosowanie, za pomocą którego można wysyłać / odbierać dane pipei tego rodzaju pliki. Mówi się, że używa się go /dev/tcp/ip/portdo połączeń tcp i /dev/udp/ip/portpakietów udp. Ponieważ mój angielski nie jest zbyt dobry, nie wiem, jak go poprawnie wyjaśnić. Edytuj pytanie i opublikuj odpowiedź.
TJM
@TJM dzięki. Pytanie dotyczyło wspomnianego pipepolecenia. Spojrzałem na https://github.com/clsr/sedbot/blob/master/sedbot.bash. Tam nie ma pipepolecenia. Definiuje dwie funkcje: readmsgi odpowiednio sendmsgdo odczytu / zapisu z / do połączenia. readmsgużywa IFS= read -r -u 3 -t "$READ_TIMEOUT" linedo odczytu z deskryptora pliku 3 do zmiennej linei sendmsgużywa echo "$(date +%s.%N) >>> $line" >&4do zapisu do deskryptora pliku 4. W każdym razie wyjaśnia to pełną metodę. Wspomnienie o „ piperozkazie” wciąż pozostaje tajemnicą dla czytelników.
arielf

Odpowiedzi:

18

To polecenie otworzyło połączenie na deskryptorze pliku 3. Aby zamknąć połączenie, musisz zamknąć deskryptor pliku 3. Aby to zrobić:

exec 3<&-
Patrick
źródło
1
Czy wykona to prawidłowe shutdown(3)wywołanie, czy tylko close(2)deskryptor pliku?
Kevin,
Robi close, ale shutdownnie jest bardziej właściwe niż zamknięcie. shutdownJedynym faktycznym zastosowaniem jest zamknięcie jednej strony gniazda dupleksu.
Patrick
4
A shutdownwysyła FIN, a closeRST. To są materialnie różne rzeczy.
Kevin,
2
@Kevin RST jest spowodowany przez zamknięcie gniazda bez uprzedniego odczytania wszystkich danych z niego. Jeśli przeczytasz do końca danych, a następnie zamkniesz, zamknięcie wyśle ​​FIN.
kasperd
@kasperd: W interfejsie API gniazda UNIX jedynym sposobem sprawdzenia, czy dane są w toku, jest albo próba odczytania z nieblokującego gniazda, albo wywołanie czegoś podobnego select()i nie sądzę, aby bash zapewniał taką opcję.
Kevin,