The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"При запуске скрипта Expect через Web"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Shell скрипты)
Изначальное сообщение [ Отслеживать ]

"При запуске скрипта Expect через Web"  +/
Сообщение от gpfspam (ok) on 28-Фев-15, 05:28 
Добрый время суток!

Не могу понять в чем проблема. Пытаюсь подтянуть инфу с железки по telnet через скриптик

#!/usr/bin/expect -f
log_user 1
spawn telnet 192.168.1.15
expect "Login:" {send "root\r";}
expect "Password:" {send "root\r"}
expect "# " {send "exit\r"}
expect eof


Первый способ (запуск через консоль).
Все прекрасно работает, на железку попадаю.

Второй способ (через WEB)
Необходимо вывести инфу на web страничку. Использую PHP. И в итоге сталкиваюсь с тем, что после ввода Login:root получаю Press any key to continue (Q to quit).

На других типах железа такого не происходит.

Неужели придется после каждой строчки ввода, обрабатывать это сообщение Press any key to continue (Q to quit).

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "При запуске скрипта Expect через Web"  +/
Сообщение от pavlinux (ok) on 02-Мрт-15, 03:25 
>[оверквотинг удален]
> expect "Login:" {send "root\r";}
> expect "Password:" {send "root\r"}
> expect "# " {send "exit\r"}
> expect eof
> Первый способ (запуск через консоль).
> Все прекрасно работает, на железку попадаю.
> Второй способ (через WEB)
> Необходимо вывести инфу на web страничку. Использую PHP. И в итоге сталкиваюсь
> с тем, что после ввода Login:root получаю Press any key to
> continue (Q to quit).

Ну в тексте явно не хватает кода ПХП

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "При запуске скрипта Expect через Web"  +/
Сообщение от gpfspam (ok) on 02-Мрт-15, 10:14 
>>[оверквотинг удален]
> Ну в тексте явно не хватает кода ПХП

#!/usr/bin/expect -f
set host [lindex $argv 0]
set login [lindex $argv 0]
set pass [lindex $argv 0]
log_user 1
spawn telnet $host
expect «Login:» {send «$login\r»;}
expect «Password:» {send «$pass\r»}
expect «# » {send «exit\r»}
expect eof

<?php
function dev($a,$b,$c)
{
exec ('./script '.$a.' '.$b.' '.$c,$vihlop);
return $vihlop;
}
print_r (dev('192.168.1.15','root','root'));
?>

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "При запуске скрипта Expect через Web"  +/
Сообщение от DiJey email(ok) on 03-Мрт-15, 12:29 
похоже железка у тебя без пароля, пароль на ней поставь ;) либо скрипт с expect дописывай

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "При запуске скрипта Expect через Web"  +/
Сообщение от gpfspam (ok) on 03-Мрт-15, 14:32 
> похоже железка у тебя без пароля, пароль на ней поставь ;) либо
> скрипт с expect дописывай

Железка по Web запаролина.
Не совсем понял, что ты имел ввиду под "скрипт с expect дописывай"? )

Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

5. "При запуске скрипта Expect через Web"  +/
Сообщение от DiJey email(ok) on 03-Мрт-15, 15:25 
>> похоже железка у тебя без пароля, пароль на ней поставь ;) либо
>> скрипт с expect дописывай
> Железка по Web запаролина.
> Не совсем понял, что ты имел ввиду под "скрипт с expect дописывай"?
> )

Сообщение:
Press any key to continue (Q to quit).
появляется если при подключении по телнету нет пароля тоесть вместо
login
password
появляется такое сообщение
соответственно что бы отрабатывали твои скрипты, нужно либо на железке установить
что бы при подключении по телнету она запрашивала логин пароль
либо доработать скрипт что бы он обрабатывал строку
Press any key to continue (Q to quit).

Пример скрипта expect использующего условия ниже


#!/usr/bin/expect

# Скрипт копирует файл или папку на хосты из списка. Параметры передаются скрипту в коммандной строке.
# Первым парамером передаем скрипту адрес файла со списков хостов, логинами и паролями формата:
# hostname1 username1 passwprd1
# hostname1 username1 passwprd1
# Вторым парамтром передаем адрес файла или папки на локальном хосте, который нужно скопировать на другие хосты
# Третьим параметром передаем адрес папки, куда скопировать файлы на удаленных хостах

set hostname_file [lindex $argv 0]
set filename [lindex $argv 1]
set path [lindex $argv 2]

set hfile [open "$hostname_file" r]                ;# Открываем файл с паролями
foreach hline [split [read $hfile] "\n"] {        ;# Разбираем файл с паролями на строки (по символу новой строки)
    set hostname [lindex $hline 0]                ;# Получаем  первое слово в строке - имя хоста
    set username [lindex $hline 1]                ;# Получаем  второе слово в строке - имя пользователя
    set password [lindex $hline 2]                ;# Получаем  третье слово в строке - пароль пользователя
    if { [string length $hostname] > 0 && [string length $username] > 0 } {        ;# Проверяем, что переменные с именем хоста и именем пользователя не пустые
    log_user 0
    spawn scp -rv $filename $username@$hostname:$path
    while 1 {
        expect {
            "*continue connecting (yes/no)?*"   {send "yes\r"}
            "*?assword:*" {send "$password\r"}
            "debug1: Exit status 0"     {send_user "Successfully copy file(s) to server $hostname\n";break}
            "Permission denied*"    {send_user "Permission denied for server $hostname\n"; break}
            "*: Not a directory"    {send_user "On server $hostname $path is not a directory!\n"; break}
            timeout     {send_user "Timeout expired for server $hostname\n"; break}
            }
        }
    log_user 1
    }
}

Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

6. "При запуске скрипта Expect через Web"  +/
Сообщение от gpfspam (ok) on 03-Мрт-15, 23:05 
>[оверквотинг удален]
>> Не совсем понял, что ты имел ввиду под "скрипт с expect дописывай"?
>> )
> Сообщение:
> Press any key to continue (Q to quit).
> появляется если при подключении по телнету нет пароля тоесть вместо
> login
> password
> появляется такое сообщение
> соответственно что бы отрабатывали твои скрипты, нужно либо на железке установить
> что бы при подключении по телнету она запрашивала логин пароль

Пароль для telnet установлен. Еще раз обрисую ситуацию. Запускаю скрипт в консоли из под root, получаю выхлоп такой:

spawn telnet 192.168.1.15
Trying 192.168.1.15...
Connected to 192.168.1.15.
Escape character is '^]'.

Login to ZXSS-I524  VERSION V1.00.0Z.00.30
Login:root
Password:

         ZXSS-I524  VERSION V1.00.0Z.00.30
Copyright(c) 2000-2006,  ZTE Corporation. All rights reserved.
--------------------------------------------------------------

# exit
Connection closed by foreign host.


Теперь пытаюсь запустить скрипт из WEB, соответственно из под apache, пользователь www-data, получаю на страничку такой вот выхлоп:

spawn telnet 192.168.1.15
Trying 192.168.1.15...
Connected to 192.168.1.15.
Escape character is '^]'.

Login to ZXSS-I524 VERSION V1.00.0Z.00.30
Login:root Press any key to continue (Q to quit)

У меня подозрения, что скрипт реагирует на пользователя запускающий его. Но права я разрешил по максимум 0777, да и скрипт бы не запускался если беда была с правами. Не могу понять где собака зарыта. А обрабатывать каждый раз это сообщение ну совсем не охота ))

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

7. "При запуске скрипта Expect через Web"  +/
Сообщение от pavlinux (ok) on 04-Мрт-15, 02:39 
> Не могу понять где собака зарыта.

stdin у апача в другом месте.


А накой ваще expect если есть ПЫХа?  


<?php
/**
* Telnet class
*
* Used to execute remote commands via telnet connection
* Usess sockets functions and fgetc() to process result
*
* All methods throw Exceptions on error
*
* Written by Dalibor Andzakovic <dali@swerve.co.nz>
* Based on the code originally written by Marc Ennaji and extended by
* Matthias Blaser <mb@adfinis.ch>
*
* Extended by Christian Hammers <chammers@netcologne.de>
* Modified by Frederik Sauer <fsa@dwarf.dk>
*
*/
class Telnet {
    private $host;
    private $port;
    private $timeout;
    private $stream_timeout_sec;
    private $stream_timeout_usec;
    private $socket  = NULL;
    private $buffer = NULL;
    private $prompt;
    private $errno;
    private $errstr;
    private $strip_prompt = TRUE;
    private $NULL;
    private $DC1;
    private $WILL;
    private $WONT;
    private $DO;
    private $DONT;
    private $IAC;
    private $global_buffer = '';
    const TELNET_ERROR = FALSE;
    const TELNET_OK = TRUE;
    /**
     * Constructor. Initialises host, port and timeout parameters
     * defaults to localhost port 23 (standard telnet port)
     *
     * @param string $host Host name or IP addres
     * @param int $port TCP port number
     * @param int $timeout Connection timeout in seconds
     * @param string $prompt Telnet prompt string
     * @param float $streamTimeout Stream timeout in decimal seconds
     * @return void
     */
    public function __construct($host = '127.0.0.1', $port = '23', $timeout = 10, $prompt = '$', $stream_timeout = 1) {
        $this->host = $host;
        $this->port = $port;
        $this->timeout = $timeout;
        $this->setPrompt($prompt);
        $this->setStreamTimeout($stream_timeout);
        // set some telnet special characters
        $this->NULL = chr(0);
        $this->DC1 = chr(17);
        $this->WILL = chr(251);
        $this->WONT = chr(252);
        $this->DO = chr(253);
        $this->DONT = chr(254);
        $this->IAC = chr(255);
        $this->connect();
    }
    /**
     * Destructor. Cleans up socket connection and command buffer
     *
     * @return void
     */
    public function __destruct() {
        // clean up resources
        $this->disconnect();
        $this->buffer = NULL;
        $this->global_buffer = NULL;
    }
    /**
     * Attempts connection to remote host. Returns TRUE if successful.
     *
     * @return boolean
     */
    public function connect() {
        // check if we need to convert host to IP
        if (!preg_match('/([0-9]{1,3}\\.){3,3}[0-9]{1,3}/', $this->host)) {
            $ip = gethostbyname($this->host);
            if ($this->host == $ip) {
                throw new Exception("Cannot resolve $this->host");
            } else {
                $this->host = $ip;
            }
        }
        // attempt connection - suppress warnings
        $this->socket = @fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout);
        if (!$this->socket) {
            throw new Exception("Cannot connect to $this->host on port $this->port");
        }
        
        if (!empty($this->prompt)) {
            $this->waitPrompt();
        }
        return self::TELNET_OK;
    }
    /**
     * Closes IP socket
     *
     * @return boolean
     */
    public function disconnect() {
        if ($this->socket) {
            if (! fclose($this->socket)) {
                throw new Exception("Error while closing telnet socket");
            }
            $this->socket = NULL;
        }
        return self::TELNET_OK;
    }
    /**
     * Executes command and returns a string with result.
     * This method is a wrapper for lower level private methods
     *
     * @param string $command Command to execute
     * @param boolean $add_newline Default TRUE, adds newline to the command
     * @return string Command result
     */
    public function exec($command, $add_newline = TRUE) {
        $this->write($command, $add_newline);
        $this->waitPrompt();
        return $this->getBuffer();
    }
    /**
     * Attempts login to remote host.
     * This method is a wrapper for lower level private methods and should be
     * modified to reflect telnet implementation details like login/password
     * and line prompts. Defaults to standard unix non-root prompts
     *
     * @param string $username Username
     * @param string $password Password
     * @return boolean
     */
    public function login($username, $password) {
        try {
            $this->setPrompt('login:');
            $this->waitPrompt();
            $this->write($username);
            $this->setPrompt('Password:');
            $this->waitPrompt();
            $this->write($password);
            $this->setPrompt();
            $this->waitPrompt();
        } catch (Exception $e) {
            throw new Exception("Login failed.");
        }
        return self::TELNET_OK;
    }
    /**
     * Sets the string of characters to respond to.
     * This should be set to the last character of the command line prompt
     *
     * @param string $str String to respond to
     * @return boolean
     */
    public function setPrompt($str = '$') {
        return $this->setRegexPrompt(preg_quote($str, '/'));
    }
    
    /**
     * Sets a regex string to respond to.
     * This should be set to the last line of the command line prompt.
     *
     * @param string $str Regex string to respond to
     * @return boolean
     */
    public function setRegexPrompt($str = '\$') {
        $this->prompt = $str;
        return self::TELNET_OK;
    }
    
    /**
     * Sets the stream timeout.
     *
     * @param float $timeout
     * @return void
     */
    public function setStreamTimeout($timeout) {
        $this->stream_timeout_usec = (int)(fmod($timeout, 1) * 1000000);
        $this->stream_timeout_sec = (int)$timeout;
    }
    
    /**
     * Set if the buffer should be stripped from the buffer after reading.
     *
     * @param $strip boolean if the prompt should be stripped.
     * @return void
     */
    public function stripPromptFromBuffer($strip) {
        $this->strip_prompt = $strip;
    } // function stripPromptFromBuffer
    /**
     * Gets character from the socket
     *
     * @return void
     */
    protected function getc() {
        stream_set_timeout($this->socket, $this->stream_timeout_sec, $this->stream_timeout_usec);
        $c = fgetc($this->socket);
        $this->global_buffer .= $c;
        return $c;
    }
    /**
     * Clears internal command buffer
     *
     * @return void
     */
    public function clearBuffer() {
        $this->buffer = '';
    }
    /**
     * Reads characters from the socket and adds them to command buffer.
     * Handles telnet control characters. Stops when prompt is ecountered.
     *
     * @param string $prompt
     * @return boolean
     */
    protected function readTo($prompt) {
        if (!$this->socket) {
            throw new Exception("Telnet connection closed");
        }
        // clear the buffer
        $this->clearBuffer();
        $until_t = time() + $this->timeout;
        do {
            // time's up (loop can be exited at end or through continue!)
            if (time() > $until_t) {
                throw new Exception("Couldn't find the requested : '$prompt' within {$this->timeout} seconds");
            }
            $c = $this->getc();
            if ($c === FALSE) {
                if (empty($prompt)) {
                    return self::TELNET_OK;
                }
                throw new Exception("Couldn't find the requested : '" . $prompt . "', it was not in the data returned from server: " . $this->buffer);
            }
            // Interpreted As Command
            if ($c == $this->IAC) {
                if ($this->negotiateTelnetOptions()) {
                    continue;
                }
            }
            // append current char to global buffer
            $this->buffer .= $c;
            // we've encountered the prompt. Break out of the loop
            if (!empty($prompt) && preg_match("/{$prompt}$/", $this->buffer)) {
                return self::TELNET_OK;
            }
        } while ($c != $this->NULL || $c != $this->DC1);
    }
    /**
     * Write command to a socket
     *
     * @param string $buffer Stuff to write to socket
     * @param boolean $add_newline Default TRUE, adds newline to the command
     * @return boolean
     */
    protected function write($buffer, $add_newline = TRUE) {
        if (!$this->socket) {
            throw new Exception("Telnet connection closed");
        }
        // clear buffer from last command
        $this->clearBuffer();
        if ($add_newline == TRUE) {
            $buffer .= "\n";
        }
        $this->global_buffer .= $buffer;
        if (!fwrite($this->socket, $buffer) < 0) {
            throw new Exception("Error writing to socket");
        }
        return self::TELNET_OK;
    }
    /**
     * Returns the content of the command buffer
     *
     * @return string Content of the command buffer
     */
    protected function getBuffer() {
        // Remove all carriage returns from line breaks
        $buf =  preg_replace('/\r\n|\r/', "\n", $this->buffer);
        // Cut last line from buffer (almost always prompt)
        if ($this->strip_prompt) {
            $buf = explode("\n", $buf);
            unset($buf[count($buf) - 1]);
            $buf = implode("\n", $buf);
        }
        return trim($buf);
    }
    /**
     * Returns the content of the global command buffer
     *
     * @return string Content of the global command buffer
     */
    public function getGlobalBuffer() {
        return $this->global_buffer;
    }
    /**
     * Telnet control character magic
     *
     * @param string $command Character to check
     * @return boolean
     */
    protected function negotiateTelnetOptions() {
        $c = $this->getc();
        if ($c != $this->IAC) {
            if (($c == $this->DO) || ($c == $this->DONT)) {
                $opt = $this->getc();
                fwrite($this->socket, $this->IAC . $this->WONT . $opt);
            } else if (($c == $this->WILL) || ($c == $this->WONT)) {
                $opt = $this->getc();
                fwrite($this->socket, $this->IAC . $this->DONT . $opt);
            } else {
                throw new Exception('Error: unknown control character ' . ord($c));
            }
        } else {
            throw new Exception('Error: Something Wicked Happened');
        }
        return self::TELNET_OK;
    }
    /**
     * Reads socket until prompt is encountered
     */
    protected function waitPrompt() {
        return $this->readTo($this->prompt);
    }
}

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

8. "При запуске скрипта Expect через Web"  +/
Сообщение от DiJey email(ok) on 04-Мрт-15, 10:52 
>[оверквотинг удален]
> spawn telnet 192.168.1.15
> Trying 192.168.1.15...
> Connected to 192.168.1.15.
> Escape character is '^]'.
> Login to ZXSS-I524 VERSION V1.00.0Z.00.30
> Login:root Press any key to continue (Q to quit)
> У меня подозрения, что скрипт реагирует на пользователя запускающий его. Но права

Пользователь тут не причем у expect нет такого условия вот он и затыкается, по скольку не знает что дальше делать.

> я разрешил по максимум 0777, да и скрипт бы не запускался
> если беда была с правами. Не могу понять где собака зарыта.
> А обрабатывать каждый раз это сообщение ну совсем не охота ))

Что мешает в expect вставить еще одну строчку?
Я же даже пример привел, предложили всё на php написать, я понимаю лень, но нельзя же быть настолько ленивым :Р .


Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

9. "При запуске скрипта Expect через Web"  +/
Сообщение от DiJey email(ok) on 04-Мрт-15, 11:14 
Я к стати посмотрел твой expect, измени его параметры проверки password login, как в моем примере, видимо доп пробел присутствует или еще что то, вот и не отрабатывает, строчка твоя выскакивает:
Press any key to continue (Q to quit)
Возможно из за длительного ожидания.
Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

10. "При запуске скрипта Expect через Web"  +/
Сообщение от pavlinux (ok) on 04-Мрт-15, 14:06 
> Возможно из за длительного ожидания.

вместо exec() passthru() юзай, но лучше все на пхп

Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру