И еще о специальном файле устройства /dev/tcp (TCP/IP), встроенном в bash

More on Using Bash's Built-in /dev/tcp File (TCP/IP)
September 30th, 2009 by Mitch Frazier in HOWTOs

В этой заметке мы рассмотрим как чтение из сокета, так и запись в него.

Перед тем как начать: вся обсуждаемая тема взята из блога Дейва Смита . Все дополнения - это сведенные в систему комментарии к оригинальному посту, а также некоторые пояснения.

Данный скрипт получает стартовую страницу с Google:

    exec 3<>/dev/tcp/www.google.com/80
    echo -e "GET / HTTP/1.1\r\nhost: http://www.google.com\r\nConnection:     close\r\n\r\n" >&3
    cat <&3

Весьма просто, всего три строки. Первая строка может озадачить, если вы не видели такой конструкции раньше. Эта строка открывает файловый дескриптор 3 на чтение и запись в устройство TCP/IP сокета. Это специальная форма директивы exec. Из страницы руководства man:

    exec [-cl] [-a name] [command [arguments]]

Если команда не задана, любое перенаправление будет иметь эффект только в данном экземпляре оболочки и код возврата всегда 0.

Таким образом, вызов exec без имени команды даёт нам способ открывать файлы в текущей shell.

После открытия сокета мы посылаем запрос HTTP через сокет с помощью echo ... >&3. Запрос содержит следующее:

    GET / HTTP/1.1
    host: http://www.google.com
    Connection: close

Каждая строка завершается символом возврата каретки и символом новой строки. Каждый заголовок заканчивается пустой строкой, которая сигнализирует окончание блока запроса (стандартное требование HTTP).

Далее мы читаем ответ из сокета с использванием cat <&3, эта команда читает выдачу и печатает её на стандартный вывод. Ответ содержит стартовую страницу Google:

    $ bash tcp.sh
    HTTP/1.1 200 OK
    Date: Wed, 30 Sep 2009 17:28:36 GMT
    Expires: -1
    Cache-Control: private, max-age=0
    Content-Type: text/html; charset=ISO-8859-1
    Set-Cookie: PREF=ID=...
    Set-Cookie: NID=27=...
    Server: gws
    X-XSS-Protection: 0
    Transfer-Encoding: chunked
    Connection: close

    fef
    <!doctype html><html><head><meta ...

Итак, что мы тут имеем? Никак консольный браузер? Что может быть проще...

Назад