Персональный
сайт
Игоря
Сысоева


 
english
обо мне
 
sysoev.ru
 
nginx
 
mod_accel
mod_realip
mod_deflate
программирование
всякая всячина
windows
freebsd
apache
pppd
unix
web
 
 

Скрипт для набора нескольких номеров

 

24.08.1999

К сожалению, chat пригоден только для написания сценариев линейных диалогов, практически не предусматривающих какое-либо ветвление. А как же быть в случае, если нужно звонить по нескольким номерам? Просто надо вызвать несколько раз chat, передавая ему каждый раз новый номер. Вот такой простенький скрипт позволяет перебирать несколько телефонных номеров:

#!/bin/sh

dial() {
    /bin/echo 1>&2
    /bin/date "+%d.%m.%Y %H:%M:%S" 1>&2

    /usr/bin/chat -V                                \
        ABORT           "ERROR"                 \
        ABORT           "NO DIALTONE"           \
        TIMEOUT         5                       \
        ""              "AT"                    \
        "OK"-"+++"-""   "AT"                    \
        "OK"            "ATZ"                   \
        "OK"            "ATS7=120"              \
        ABORT           "BUSY"                  \
        ABORT           "NO ANSWER"             \
        ABORT           "NO CARRIER"            \
        ABORT           "Login incorrect"       \
        "OK"            "ATDP$1"                \
        TIMEOUT         125                     \
        "CONNECT"       "\\с"                   \
        TIMEOUT         30                      \
        "ogin:"         "igor"                  \
        "assword:"      "1234567"               \
        "}"             "\\с"

    if [ "$?" = "0" ]; then
        exit 0
    fi

    /bin/echo 1>&2
    /bin/echo "$1 failed" 1>&2
}

dial 5551234
dial 5552345
dial 5553456

exit 1

Запишем этот скрипт в файл /etc/ppp/dial и не забудем сделать его исполняемым:

chmod +x /etc/ppp/dial

Сценарий диалога на этот раз мы указали в командной строке chat. Обратите внимание, что у управляющего символа "\c" добавился ещё один бэкслэш — "\\c", потому что шелл заменит наш "\c" на просто "c". Кроме того, вместо номера телефона мы поставили $1, в этой переменной хранится номер телефона, переданный процедуре dial() в качестве параметра. В остальном сценарий остался таким же. Необходимость добавления обратного слэша относится и к другим управляющим символам, которые поддерживает chat, например, "\q".

Основная процедура скрипта — dial(). Мы вызываем её три раза — по числу номеров, и в случае, если не смогли дозвонится ни по одному из них, выходим с кодом 1. Ключ -V у chat и команды echo и date нужны только в том случае, если Вы планируете вести журнал — echo будет отделять звонки отделять друг от друга пустыми строками, а date будет записывать время каждого звонка. Поскольку эти команды выводят в стандартный поток вывода — stdout, а журнал будет сниматься из стандартного потока вывода ошибок — stderr, необходимо направить stdout этих команд в stderr с помощью 1>&2. Если Вы используете chat с ключом -v, то команды echo и date не нужны, поскольку лог будет вестись через syslogd, который записывает время каждого сообщения.

Итак, dial() записывает время звонка и вызывает chat -V с длинной строкой сценария диалога. После завершения работы chat мы проверяем его код выхода — если он равен "0", значит chat успешно дозвонился, и мы выходим из скрипта с кодом "0". Если же chat не удалось соединится, мы записываем это в в стандартный поток вывода ошибок.

Для корректной работы этого скрипта необходимо, что бы время ожидания соединения для chat было несколько больше, чем у модема. В нашем случае, это соответственно 125 и 120 секунд. Предположим, что chat ждёт строку "CONNECT" 115 секунд. По истечении этого времени chat завершит свою работу, а модем все ещё будет висеть на линии. Если в этот момент скрипт вызовет chat для набора другого номера, chat запишет в модем строку "AT", на что модем сразу же положит трубку и вернёт сообщение "NO CARRIER". chat прочитает этот "NO CARRIER" и, не дождавшись в течение 5 секунд сообщения "OK", завершит работу, даже не пытаясь набрать номер. Указывать одинаковое время не рекомендуется, поскольку вероятность того, что в модеме и компьютере оно будет всё же различно, достаточно велика.

В принципе, сценарий диалога chat можно разместить в отдельном файле /etc/ppp/script, тогда процедура dial() будет выглядеть так:

dial() {
    /bin/echo 1>&2
    /bin/date "+%d.%m.%Y %H:%M:%S" 1>&2

    /usr/bin/chat -V -T $1 -f /etc/ppp/script

    if [ "$?" = "0" ]; then
        exit 0
    fi

    /bin/echo 1>&2
    /bin/echo "$1 failed" 1>&2
}

Обратите внимание, что номер телефона, который процедура dial() хранит в переменной $1, передаётся chat с помощью параметра -T. Поэтому наш первоначальный сценарий нужно немного изменить:

ABORT           "NO ANSWER"
ABORT           "NO CARRIER"
ABORT           "Login incorrect"
"OK"            "ATDP\T"
TIMEOUT         125
"CONNECT"       "\c"
TIMEOUT         30

Вместо управляющего символа "\T" chat подставит значение параметра -T, то есть телефонный номер. Кроме "\T", chat воспринимает ещё один управляющий символ "\U" и соответствующий ему параметр -U. Этим параметризация сценариев и ограничена. Если Вам нужно больше двух параметров, то придётся задать сценарий chat в командной строке.

(C) Игорь Сысоев
http://sysoev.ru