24.08.1999, © Igor Sysoev, igor@nitek.ru

 

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

 

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

#!/bin/sh

dial () {
        /bin/echo 1>&2
        /bin/date "+%d.%m.19%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.19%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 в командной строке.