Как разорвать TCP-соединение, установленное самим bash?

17

Я использовал exec 3<>/dev/tcp/192.168.0.101/6435для установления соединения TCP с 192.168.0.101:6435. И я получил, а также отправил несколько сообщений с pipeкомандой.

Теперь я хочу разорвать соединение TCP. Но, как ss -anpetя вижу, bash сам удерживает эту связь, не разветвляя дочерний процесс.

Я пытался послать сигнал 9 и 15 процессу bash, но, как вы знаете, bash не может убить себя.

Итак, могу ли я разорвать установленное мною TCP-соединение, не прерывая те точки, которые я использую (ни убивая его root, ни отправляя Ctrl + D)?

TJM
источник
Не могли бы вы получить еще одну раковину и убить ее bash?
trysis
3
bashконечно, может убить себя - хотя это на самом деле не то, что вы хотите сделать здесь!
psmears
@TJM, чтобы сделать этот увлекательный вопрос более полезным для других, не могли бы вы рассказать о pipeкоманде, которую вы используете, и которую я не могу найти в моей системе? Из какой упаковки pipeпоступает? Какие (примерные) параметры вы можете передать ему для отправки / получения данных по /dev/tcp/...соединению? Благодарю.
Ариэльф
@arielf Как правило, я новичок в области компьютерных наук, и я нашел этот вид использования в сценарии оболочки bash под названием sedbot, его можно найти на Github. Да, я не могу найти никаких файлов /dev/tcp, даже не могу найти /dev/tcpсебя. Но, кажется, это специальное использование, с которым вы можете отправлять / получать данные pipeи файлы такого типа. Говорят, что использовать /dev/tcp/ip/portдля tcp-соединений и /dev/udp/ip/portдля пакетов udp. Поскольку мой английский не очень хорош, я не знаю, как это правильно объяснить. Пожалуйста, не стесняйтесь редактировать вопрос и опубликовать ответ.
TJM
@TJM спасибо. Вопрос был о pipeкоманде, которую вы упоминаете. Я посмотрел на https://github.com/clsr/sedbot/blob/master/sedbot.bash. Там нет pipeкоманды там. Он определяет две функции: readmsgи sendmsgдля чтения / записи из / в соединение соответственно. readmsgиспользует IFS= read -r -u 3 -t "$READ_TIMEOUT" lineдля чтения из файлового дескриптора 3 в переменную lineи sendmsgиспользует echo "$(date +%s.%N) >>> $line" >&4для записи в файловый дескриптор 4. В любом случае, это проясняет полный метод. pipeУпоминание о « команде» до сих пор остается загадкой для читателей.
Ариэльф

Ответы:

18

Эта команда открыла соединение по файловому дескриптору 3. Поэтому, чтобы закрыть соединение, вам необходимо закрыть файловый дескриптор 3. Для этого:

exec 3<&-
Патрик
источник
1
Будет ли это сделать правильный shutdown(3)вызов или просто close(2)дескриптор файла?
Кевин
Делает close, но shutdownне более правильно, чем близко. shutdownЕдинственное реальное использование - это когда вы хотите закрыть только одну сторону дуплексного сокета.
Патрик
4
А shutdownотправляет FIN, а closeотправляет RST. Это материально разные вещи.
Кевин
2
@Kevin RST вызвано закрытием сокета без предварительного чтения всех данных из него. Если вы прочитали данные до конца, а затем сделали закрытие, закрытие отправит FIN.
Касперд
@kasperd: В API сокетов UNIX единственный способ узнать, есть ли ожидающие данные данные, это либо попытаться прочитать данные из неблокирующего сокета, либо вызвать что-то подобное select(), и я не верю, что bash предоставляет какой- либо вариант.
Кевин