wait_out (buffer) не захватывает все данные при вызове через php - PullRequest
2 голосов
/ 03 июля 2019

Я пытаюсь получить сведения о конфигурации от коммутатора через ожидаемый сценарий.
У меня ниже работает нормально, как я ожидал, когда я звоню через оболочку вручную. Но когда то же самое вызывается через, php (чтобы создать веб-интерфейс для вызова этого) каким-то образом wait_out (буфер) не заполняет все строки, и мое совпадение завершается неудачей.

Я пытаюсь соответствовать установленный бит конфигурации или нет.
Опять же, код работает при вызове вручную, просто через php это как-то не в состоянии заполнить wait_out (buffer) :(: (


Рабочий код.

#!/usr/bin/expect
set ip ROUTER_IP
set uname USER_NAME
set psd PASSWORD
set log_file -a "/tmp/script.log"
spawn /usr/bin/ssh $uname@$ip
expect {
    "ord:" {
        send "$psd\r"
        expect {
            "> " {
                send "\r"
                set cmd "show configuration | display set | match class | match rancid"
                set values $expect_out(buffer)
                send_log "\nbefore trim n match -$values-\n"
                set values [string trim $values]
                send_log "\nbefore match -$values-\n"
                set found [regexp {match rancid\s+(.*)\s+\r\n\{.*} $values match px]
                if { $found == 1  && $px != "" } {
                    puts "Rancid Exists... !!!"
                    send "exit\r"
                    exit 1
                } else { 
                    puts "Coundnt find Rancid ... !!!"
                    send "exit\r"
                    exit 2
                }
            }
            "denied: " {
                puts "ERROR: Access Denied"
                exit 2
            }
        }
    }
}

Я звоню через php вот так

$res=shell_exec("/usr/bin/expect $scriptPath ");

Я мог видеть, что ожидаемый_каталог (буфер), для которого установлено значение $ values, заполняется половиной команд, выводимых из файла журнала.

Успешное ожидание (буфер),

before trim match -show configuration | display set | match class | match rancid ^M
set system login user rancid class remote-backup^M
^M
{master:1}^M
USER_NAME@SWITCH> -

before match -show configuration | display set | match class | match rancid ^M
set system login user rancid class remote-backup^M
^M
{master:1}^M
USER_NAME@SWITCH>-

при вызове через php Ожидаемый_буток (буфер) выглядит следующим образом:

before trim match -show configuration | display set | m^MUSER_NAME@SWITCH> -

before match -show configuration | display set | m^MUSER_NAME@SWITCH>-

Каким-то образом, когда ожидается сценарий, вызываемый через php, в буфер не выводятся все команды, и сопоставление завершается неудачно.
Может кто-нибудь подсказать мне, в чем может быть ошибка. Спасибо.

1 Ответ

0 голосов
/ 03 июля 2019

Почему вещи отличаются?Ну, есть много возможных причин.Различные сроки могут быть одним из них;это очень возможно и очень трудно предотвратить.Вы просто должны написать свой код, чтобы приспособиться к вариации;к счастью, это довольно просто.

В общем, использование $expect_out(buffer) само по себе не рекомендуется, так как не определяет, сколько данных в нем накапливается.Вероятно, он будет иметь столько, сколько нужно для соответствия шаблону expect ed, но на самом деле он не будет соответствовать гораздо большему.Я ожидаю, что скрипт будет выглядеть примерно так:

#!/usr/bin/expect
set ip ROUTER_IP
set uname USER_NAME
set psd PASSWORD
set log_file -a "/tmp/script.log"
spawn /usr/bin/ssh $uname@$ip

# Less nesting here! Makes the code much simpler to read
expect "ord:"
send "$psd\r"
expect {
    "> " {
        send_log "logged in\n"
    }
    "denied: " {
        puts "ERROR: Access Denied"
        exit 2
    }
}

# Classic code to read a multi-line result from a remote site, ONE LINE AT A TIME
set cmd "show configuration | display set | match class | match rancid"
send "$cmd\r"; # Had you forgotten this in pasting?
set values ""
expect {
    -re {^(.*\S|)\r?\n} {
        append values $expect_out(1,string) "\n"
        exp_continue
    }
    "> " {
        # Got the prompt again
    }
}

# This is your code again
send_log "\nbefore trim n match -$values-\n"
set values [string trim $values]
send_log "\nbefore match -$values-\n"
set found [regexp {match rancid\s+(.*)\s+\r\n\{.*} $values match px]
if { $found == 1  && $px != "" } {
    puts "Rancid Exists... !!!"
    send "exit\r"
    exit 1
} else { 
    puts "Coundnt find Rancid ... !!!"
    send "exit\r"
    exit 2
}

В общем, вы должны попытаться структурировать свой код так, чтобы вы чередовали свои expect s и send s, хотя последовательностьнескольких expect с может быть в порядке.Тем не менее, вы можете думать об этом, как будто send не обрабатывается до следующего expect.

Обратите внимание на использование exp_continue.Это очень мощная функция Expect, которая позволяет поддерживать текущее выражение expect в большей степени.Это позволяет вам создавать циклы соответствия, такие как тот, который я сделал, и значительно упрощает многие проблемы взаимодействия.И ради всего святого, постарайтесь не вкладывать код как можно больше!Программы достаточно сложные, не усложняя их!

...