PDA

Bekijk de volledige versie : expect на shell, или авто-телнеттинг



al37919
09-05-2007, 10:50
В этом треде оказались административно объединены две малосвязанные вещи --- нативная компиляция expect с выложенными бинарниками достаточно древних версий expect и tcl, и весьма любопытный скрипт от cyrax вынесенный в название темы. Читателям, которые интересуются собственно темой треда, рекомендую пропустить первые 11 постов и идти сразу сюда: expect на shell, или авто-телнеттинг (http://wl500g.info/showpost.php?p=77874&postcount=12)

----------

Наблюдается многократно обсуждавшаяся проблема, что при разрыве соединения (предположительно со стороны провайдера), соединение не восстанавливается и в логе возникает (иногда многочасовая) вереница сообщений:

May 9 11:27:33 pppd[6319]: Timeout waiting for PADO packets
May 9 11:27:33 pppd[6319]: Unable to complete PPPoE Discovery

Олег рекомендовал выставить в дополнительных опциях pppd "maxfail 0", у меня в этой строке в веб-интерфейсе не стоит ничего, однако pppd запускается коммандой pppd file /tmp/ppp/options.wan0, и файл /tmp/ppp/options.wan0 содержит:


noauth refuse-eap
user xxx
password xxx
nomppe nomppc
plugin rp-pppoe.so rp_pppoe_service 'stream' nic-vlan1
mru 1492 mtu 1492
maxfail 0
usepeerdns
persist
ipcp-accept-remote ipcp-accept-local noipdefault
ktune
default-asyncmap nopcomp noaccomp
novj nobsdcomp nodeflate
lcp-echo-interval 10
lcp-echo-failure 6
unit 0

Т.е. эта опция включена по дефолту

Проблема решается в 95% случаев путем перезагрузки ADSL модема.

Теперь собственно мой вопрос. Я могу сделать какую-нибудь сторожевую собаку, которая будет проверять лог на предмет этой ошибки и дальше хотелось бы удаленно перезагрузить модем. На модеме стоит тоже линукс, поддерживается логин через ssh и telnet. Как его перезагрузить...?

Один вариант мне видится таким --- создать специального юзера и сделать ему логин-шелл=/sbin/reboot , но честно говоря это означает модификацию прошивки модема, к чему я морально не готов...

В идеале хотелось бы что то вроде удаленного sh -c , но ничего подобного не могу найти

P.S. Провайдер --- стрим, ADSL модем Dlink DSL-500T, wl500gP (7g)

Mirage-net
09-05-2007, 10:58
На модеме стоит тоже линукс, поддерживается логин через ssh и telnet. Как его перезагрузить...?

Один вариант мне видится таким --- создать специального юзера и сделать ему логин-шелл=/sbin/reboot , но честно говоря это означает модификацию прошивки модема, к чему я морально не готов...

В идеале хотелось бы что то вроде удаленного sh -c , но ничего подобного не могу найти

P.S. Провайдер --- стрим, ADSL модем Dlink DSL-500T, wl500gP (7g)

Так вчем проблема? Заходим по SSH и ребутим ... или я не понял вопроса...
инфа для размышления http://www.lghost.ru/lib/samag/content/2006/samag_01_38/samag1(38)-12-14.pdf

al37919
09-05-2007, 11:25
Спасибо за сценарии на перле. Это как раз то что надо. Я и сам думал что то подобное сделать с помощью expect, но понадеялся может есть готовое решение попроще. Впрочем expect --- тоже гут :) , жалко нет в пакетах.

Mirage-net
09-05-2007, 11:29
Спасибо за сценарии на перле. Это как раз то что надо. Я и сам думал что то подобное сделать с помощью expect, но понадеялся может есть готовое решение попроще. Впрочем expect --- тоже гут :) , жалко нет в пакетах.

Ну и что что нет в пакетах ... можно самому скомпилить ... но в нем немного не удобно с текстом работать (а ведь нужно лог обрабатывать) в прочем вариантов полно главное идея :)

al37919
13-05-2007, 22:28
но в нем немного не удобно с текстом работать (а ведь нужно лог обрабатывать)
с этим не соглашусь в корне --- tcl прекрасно поддерживает regexp.

В общем, в результате, таки откомпилил expect и сделал в нем (лежит у меня все таки душа больше к tcl нежели к perl :) ). expect отказался кросс-компилиться со следующей ошибкой (выдаваемой ./configure):
checking if WNOHANG requires _POSIX_SOURCE... configure: error: Expect can't be cross compiled
Эту ошибку я побороть не смог (если кто понимает как это обойти --- feedback is welcome). В результате сделал нативную компиляцию обоих последних версий (как expect-5.43, так и tcl-8.4.14 ) [tcl пришлось побить на две части, т.к. аттачмент ограничен 1 Мб]. Не ведаю как изготовить ipk путем нативной компиляции, так что прилагаю просто билды как первого, так и второго ( обращаю внимание, что они скомпилены для установки в /opt/local, а не в /opt , так что пути в /opt/local/bin , /opt/local/man , /opt/local/share/man должны быть прописаны куда следует)

В результате автоматическая перезагрузка ADSL модема у меня выглядит следующим образом (ежепятиминутно наличие соединения проверяется путем запуска из крона):
/opt/etc/cron.5mins/check_adsl.exp:

#!/bin/sh
# The following line is executed by /bin/sh and not by expect \
exec expect -f "$0" ${1+"$@"}

proc check1 {} {
spawn ping -c 10 www.stream.ru
expect {
-re {\d*\sbytes\sfrom\s[\d\.]*:\sicmp_seq=\d*\sttl=\d*\stime=[\d\.]*\sms} exit
}
check2
}

proc check2 {} {
spawn tail -n 3 /opt/var/log/syslog.log
expect {
"Timeout waiting for PADO packets" reboot_adsl
"Unable to complete PPPoE Discovery" reboot_adsl
}
}

proc reboot_adsl {} {
spawn telnet 192.168.2.1
expect -exact "login: "
send -- "admin\r"
expect -exact "Password: "
send -- "XXXXXXXX\r"
expect -exact $::prompt_adsl
send -- "reboot\r"
set timeout 10
expect
exec logger "$::argv0\[[pid]\]: Rebooting ADSL modem."
puts ""
}

set timeout 60

set prompt_adsl "\r
# "

check1

al37919
13-05-2007, 22:31
А может как раз expect задействовать [это типа в виде обмена идеи на идею :) . Он как раз с курсами общаться могет: http://expect.nist.gov/FAQ.html#q22 ] :)
http://wl500g.info/showpost.php?p=55065&postcount=5

Oleg
14-05-2007, 12:05
Я думаю, что можно перегрузить его и с помощью wget.

ЗЫ: у меня DSL-500G, без линуха, работает месяцами без проблем. :)

ЗЫЫ: А ещё, я не использую Service Name вообще.

al37919
14-05-2007, 12:20
wget??? Т.е. послать через wget ту инструкцию, которая выполняется при нажати кнопки save&reboot или как там она называется? Любопытно попробовать.
P.S. У этого случается заскок где то раз в неделю. Правда, обычно, когда что то подобное начинается, то повторяется несколько раз довольно часто, потом опять редко. Т.е., похоже, что-то происходит у провайдера. Вообще, для этого зверя тоже есть альтернативная прошивка, надо ее наконец будет попробовать.

Oleg
14-05-2007, 12:27
Да, про wget всё правильно. Возможно прийдётся использовать нормальный wget из пакетов. Или curl.

Что касается СТРИМа, то если перегрузка модема помогает, то дело не в провайдере.

Rambalac
14-05-2007, 12:39
приклеить к кнопке включения палочку, положить рядом сдюк подключенный к компу, если надо перегрузить, выдвигаем удаленно сидюк, он своим выдвижным столом давит на палочку, та на кнопочку :)

al37919
14-05-2007, 21:44
При нажатии на 'Save and restart' вызывается:

function SaveNBoot()
{
if(remote_user=="user")
{
alert("sorry, you're not authorised to modify this page.");
return false;
}
if(confirm("Save and restart?"))
{
document.getElementById("uiPostVarName").name = "logic:command/save";
document.getElementById("pagename").value = "../html/tools/restartmodem.htm";
document.getElementById("commandname").value="restart";
document.getElementById("uiPostrestart").value="1";
document.getElementById("pppdisconnect").disabled = false;
document.getElementById("uiPostForm1").submit();
}
}
/usr/www/html/tools/restartmodem.htm:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="../html/css/common.css" type="text/css">
<script language="JavaScript" src="../html/js/menu1.js"></script>
<script type='text/javascript'>
function callset()
{
if(document.getElementById("uiPostrestart").value == 1)
{
<? if eq $var:com restart `document.getElementById("uiPostVarName").name = "logic:command/reboot";`
'document.getElementById("uiPostVarName").name = "logic:command/defaults";' ?>
document.getElementById("uiPostrestart").value = 0;
document.getElementById("uiPostForm").submit();
}
// modify by Jarry for whether the lan IP change make sure the Reboot or Restore is correct 2005/02/19
//else
//{
<? if eq $var:com restart `setTimeout('document.location.href="http://<? query lan0:static:settings/ip ?>/cgi-bin/webcm?getpage=../html/index.html"', 45000);``<? if eq $var:ip restore `setTimeout('top.location.href="http://<? query lan0:static:settings/ip ?>/cgi-bin/webcm?getpage=../html/index.html"', 35000);`
`setTimeout('document.location.href="../html/index.html"', 35000);` ?>` ?>
//}

//setTimeout('document.location.href="http://192.168.1.1/cgi-bin/webcm?getpage=../html/index.html"', 42000);
}

</script>
</head>
<body topmargin=20 onload="callset()">
<script type='text/javascript'>
mainTableStart();
MapContent();
logo();
secondRow();
ThirdRowStart();
//Write_Item_Images();//left area
ThirdRowEnd();
inTableStart();
</script>

<table width=540px border=0 cellpadding=0 cellspacing=0 align=top height="500px">

<tr>
<td colspan=6 height="40" nowrap class="tabhead">Restarting...</td>
</tr>

<tr>
<td class="tabdata" height="50">The system is now restarting. Please wait.</td>
</tr>

<tr><td colsapn="6"></td></tr>
</table>





<script type='text/javascript'>
inTableEnd();
mainTableEnd();
</script>

<form method="POST" action="webcm" target="_self" id="uiPostForm" >
<!--
<input type="hidden" name="getpage" id="pagename" value="../html/tools/restartmodem.htm">
-->
<input type="hidden" name="getpage" id="pagename" value="../html/home/home_wizard.htm">
<input type="hidden" name="var:restart" value="<? echo $var:restart ?>" id="uiPostrestart">
<input type="hidden" id="uiPostVarName" name="" value="">

</form>

</body>
</html>
т.е. вроде такая страница есть, но каким должен быть url, чтобы вызвать корректное действие... ?
http://192.168.2.1/tools/restartmodem.htm показывает страницу:

Restarting...
The system is now restarting. Please wait.
и ничего не делает. Надо передавать параметры... А как их передать если метод POST?

Вроде с expect все как то проще получается:)

cyrax
16-01-2008, 20:30
Привет,

да, давно не заходил сюда.

В общем хочу поделиться недавно написанным скриптом для тех, кому нужен expect (например для автоматической работы через телнет или вроде того).

Конечно есть пакет py_expect, но он на питоне и это не всегда удобно или возможно. Вот для таких случаев и будет полезен мой скрипт.

Для начала - пример, как это работает. В качестве примера - получение даты с другого устройства, например на DSL модеме.



#!/bin/sh

. /usr/local/sbin/mini-tools/expect.lib.sh
# цепляем библиотеку (ее код дан ниже)

expect_open -c telnet 192.168.10.1
# использование: expect_open [-c | -e <filename> ] <command> ....
#опция -с включает дублирование вывода на консоль
#опция -e включает дублирование вывода в <filename>
#без опций - вывода нет

expect login
# ждем строку включающую в себя login - запрос имени пользователя

send_line admin
# отправляем строку с именем пользователя "admin" и перевод строки

expect_eol
# ждем перевод строки, который мы же и отправили ;)

expect Password
send_line password
expect_eol

expect_exact '#'
# ждем строку состоящую только из # - запрос от shell'а

expect_echo_start
# для примера - включение вывода на консоль с этого момента

send_line "date +%s;date +%m%d%H%M%Y.%S"
expect_eol

expect_capture_start
# начало захвата вывода в переменную $EXPECT_OUTPUT, очищает переменную

expect_eol
# ждем перевода строки, т.е. в $EXPECT_OUTPUT будет вывод от первого date

if [ $EXPECT_OUTPUT -le 86400000 ]; then
echo 'Modem time is invalid'
elif [ $EXPECT_OUTPUT -le `date +%s` ]; then
echo 'Modem time is out-of-date'
else
expect_capture_start
expect_eol
#захватываем строку от второй команды date

expect_capture_stop
echo "Modem time is: $EXPECT_OUTPUT"
# date -s $EXPECT_OUTPUT
fi

expect_close
# закрываем запущенный процесс (телнет)


Ну а теперь все остальное. Немного замудрено конечно с пайпами, но зато не надо в разных файлах ввод и вывод делать.

Из того, что точно криво сделано - это вхождение строки проверяю через вызов grep, т.к. ~= дает ошибку, а другого способа не знаю.

И еще не знаю как убрать CR когда он попадает в строку - это вызывает проблему с expect_exact если им ждать вывод с переводом строки.

Из того, что не доделано - таймаут. Мне он не оч нужен, но это не сложно, и если будут желающие, то постараюсь прикрутить.

expect.lib.sh


#!/bin/sh
local EXPECT_APP_PIPE_IN
local EXPECT_APP_PIPE_OUT
local EXPECT_APP_ECHO
local EXPECT_INJECT_LINE
local EXPECT_OUTPUT
local EXPECT_CAPTURE=false
local EXPECT_APP_ID

expect_open () { # $1=echo_file $2+=app
case "$1" in
'-e') shift; expect_echo_start "$1"; shift;;
'-c') shift; expect_echo_start;;
*) expect_echo_stop;
esac
local RUN="$@"
set `dd if=/dev/urandom bs=1 count=4 2>/dev/null|od -D`
RND=${2##0000000 }
RND=${RND%% 0000004}
readonly EXPECT_APP_PIPE_IN=/tmp/tmp.$$.$RND.pipe-in
mkfifo $EXPECT_APP_PIPE_IN
readonly EXPECT_APP_PIPE_OUT=/tmp/tmp.$$.$RND.pipe-out
mkfifo $EXPECT_APP_PIPE_OUT
readonly EXPECT_INJECT_LINE="-INJECT-$$-$RND-"
$RUN <$EXPECT_APP_PIPE_IN >$EXPECT_APP_PIPE_OUT &
EXPECT_APP_ID=$!
exec 8>$EXPECT_APP_PIPE_IN #/proc/$EXPECT_APP_ID/fd/1
exec 9<$EXPECT_APP_PIPE_OUT
usleep 100000 #need to get the spawned app running as it is in background
}

expect_handle_input () { #$1 - handler #$2+ - handler params
local BUFFER
local LINE
local N_LINE
local RET_RES
local HANDLER=$1
shift
local PARAMS="$@"
local HAD_DATA_LINE=false
export HAD_DATA_LINE
local STOP_LINE=false
export STOP_LINE
while true; do
echo $EXPECT_INJECT_LINE >$EXPECT_APP_PIPE_OUT
while read N_LINE <&9; do
STOP_LINE=false
LINE="${N_LINE%$EXPECT_INJECT_LINE}"
if [ "$N_LINE" == "$LINE" ]; then
HAD_DATA_LINE=true
LINE="$BUFFER${LINE%%' '}"
BUFFER=""
echo "$LINE" >$EXPECT_APP_ECHO
if $EXPECT_CAPTURE; then EXPECT_OUTPUT="$EXPECT_OUTPUT$LINE"; fi
# FULL-LINE
$HANDLER 0 "$LINE" "$@"
elif [ "$LINE" ]; then
BUFFER="$BUFFER$LINE"
LINE="${BUFFER}"
# PART-LINE
$HANDLER 1 "$LINE" "$@"
else
STOP_LINE=true
# HAD_DATA_LINE? PART-LINE
$HANDLER 2 "$LINE" "$@"
fi
RET_RES=$?;
if [ $RET_RES -ne 1 ]; then
if [ "$BUFFER" ]; then
echo -n "$LINE" >$EXPECT_APP_ECHO
if $EXPECT_CAPTURE; then EXPECT_OUTPUT="$EXPECT_OUTPUT$LINE"; fi
fi
return $RET_RES
elif $STOP_LINE || [ "$BUFFER" ]; then
break
fi
done
if [ ! -d /proc/$EXPECT_APP_ID ]; then
break
fi
usleep 50000
done
echo "$BUFFER" >$EXPECT_APP_ECHO
if $EXPECT_CAPTURE; then EXPECT_OUTPUT="$EXPECT_OUTPUT$LINE"; fi
return 2
}

__input_handler_match_any () {
if $STOP_LINE && $HAD_DATA_LINE; then
return 0
fi
return 1
}
__input_handler_match_all () {
return 1
}
__input_handler_match_eol () {
if [ $1 == 0 ]; then
return 0
fi
return 1
}
__input_handler_grep () {
if echo "$2" | grep "$3" > /dev/null ; then
return 0
fi
return 1
}

__input_handler_match () {
local T="${2%% }"
if [ "${T## }" == "$3" ]; then
return 0
fi
return 1
}

expect_any_line () {
expect_handle_input __input_handler_match_any
}

expect () {
expect_handle_input __input_handler_grep "$1"
}
expect_exact () {
expect_handle_input __input_handler_match "$1"
}
expect_eol () {
expect_handle_input __input_handler_match_eol
}
send () {
echo -n "$@" >&8
}
send_line () {
echo "$@" >&8
}
expect_capture_start () {
EXPECT_OUTPUT=''
EXPECT_CAPTURE=true
}
expect_capture_continue () {
EXPECT_CAPTURE=true
}
expect_capture_stop () {
EXPECT_CAPTURE=false
}
expect_echo_start () {
if [ "$1" ]; then
EXPECT_APP_ECHO="$1"
else
EXPECT_APP_ECHO=/proc/$$/fd/1
fi
}
expect_echo_stop() {
EXPECT_APP_ECHO='/dev/null'
}
expect_close_now() {
exec 8>&-
exec 9<&-
rm $EXPECT_APP_PIPE_IN
rm $EXPECT_APP_PIPE_OUT
}
expect_close() {
exec 8>&-
if [ "$EXPECT_APP_ECHO" != '/dev/null' ]; then
expect_handle_input __input_handler_match_all
fi
exec 9<&-
rm $EXPECT_APP_PIPE_IN
rm $EXPECT_APP_PIPE_OUT
}
expect_clean_up() {
exec 8>&-
exec 9<&-
rm /tmp/tmp.$$.*.pipe-in
rm /tmp/tmp.$$.*.pipe-out
}


Надеюсь будет полезно кому-нить.
Если что - пишите, но быстрой реакции не обещаю.

A1ex
27-03-2008, 20:31
Я гашу "детский" комп через ssh. sshd на винде организовать не так уж сложно. Есть пакет copSSH. Это openssh из cygwin оформленный в виде виндового инсталятора. При установке могут быть проблеммы с именем группы Администраторы, тогда надо переименовать на латиницу. Сейчас не помню где было такое, под XP, w2k3 или вистой.
Я юзаю openssh и другие полезные линуксовые утилиты устанавливая cygwin. В этом случае для запуска sshd доки нужно читать ;).

piezomotor
28-03-2008, 13:33
Я гашу "детский" комп через ssh. sshd на винде организовать не так уж сложно. Есть пакет copSSH. Это openssh из cygwin оформленный в виде виндового инсталятора. При установке могут быть проблеммы с именем группы Администраторы, тогда надо переименовать на латиницу. Сейчас не помню где было такое, под XP, w2k3 или вистой.
Я юзаю openssh и другие полезные линуксовые утилиты устанавливая cygwin. В этом случае для запуска sshd доки нужно читать ;).

A1ex, А вот у меня стоит OpenVPN на "детском" компе. Стало быть он автоматом коннектится к роутеру.

А вот как "гасть" "детский" комп через OpenVPN пока в голову не пришло...

У вас есть идеи?

sonice
02-04-2008, 03:57
Я гашу "детский" комп через ssh. sshd на винде организовать не так уж сложно. Есть пакет copSSH. Это openssh из cygwin оформленный в виде виндового инсталятора. При установке могут быть проблеммы с именем группы Администраторы, тогда надо переименовать на латиницу. Сейчас не помню где было такое, под XP, w2k3 или вистой.
Я юзаю openssh и другие полезные линуксовые утилиты устанавливая cygwin. В этом случае для запуска sshd доки нужно читать ;).

Спасибо большое за идею! Я тут http://www.itefix.no/phpws/index.php?module=pagemaster&PAGE_user_op=view_page&PAGE_id=12

нашел прогу для винды openssh

Установил, Настроил, РАБОТАЕТ! Теперь гашу "детский" комп "вручную" c Putty-

ssh username@192.158.1.51
ввожу password
shutdown -s

Хочу это автоматизировать, чтобы запускать кроном...
и теперь Сделал скрипт-remotepcshutdown.sh

#!/bin/sh
spawn ssh username@192.158.1.51
expect "Password:"
send "password\r"
send "shutdown -s"


Но не заработало- выдает-

./remotepcshutdown.sh: ./remotepcshutdown.sh: 2: spawn: not found
./remotepcshutdown.sh: ./remotepcshutdown.sh: 3: expect: not found
./remotepcshutdown.sh: ./remotepcshutdown.sh: 4: send: not found
./remotepcshutdown.sh: ./remotepcshutdown.sh: 5: send: not found

А как исправить?

Спасибо!

al37919
02-04-2008, 07:16
spawn, expect, send --- это что? Уж больно сильно напоминает tcl-ный expect. Тогда рекомендую ознакомиться с этим: http://wl500g.info/showthread.php?t=9292
А есть еще такая тема: http://wl500g.info/showthread.php?t=12492

piezomotor
02-04-2008, 19:10
Я ссылаюсь на http://wl500g.info/showpost.php?p=91357&postcount=23

Вот все работает "вручную"-


$ ssh myusername@192.168.1.55
myusername@192.168.1.55's password:
Last login: Tue Apr 1 23:22:39 2008 from 192.168.1.1

myusername@mypcname ~
$


хочу автоматизировать через крон...

сделал файл - /opt/etc/expect.lib.sh

сделал скрипт- remotepcshutdown.sh

#!/bin/sh
. /opt/etc/expect.lib.sh
expect_open ssh myusername@192.168.1.55
expect_eol
expect Password
send_line mypassword
expect_eol
send_line shutdown -s
expect_eol

когда запускаю ./remotepcshutdown.sh то выдает-


./remotepcshutdown.sh
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected


А если меняю скрипт- remotepcshutdown.sh

#!/bin/sh
. /opt/etc/expect.lib.sh
send_line ssh myusername@192.168.10.55
expect_eol
expect Password
send_line mypassword
expect_eol
send_line shutdown -s
expect_eol


То получаю-

./remotepcshutdown.sh: ./remotepcshutdown.sh: 5: 9: Bad file descriptor
./remotepcshutdown.sh: ./remotepcshutdown.sh: 5: cannot create : Directory nonexistent


В чем тут дело? Может кто подскажет?

6opoga
03-04-2008, 08:18
Как-то это слишком. Я бы сделал что.
1) Сгенерировал бы пару ключей
2) Публичный положил бы на целевое устройство в ~/.ssh, закрытый - на роутер
3) На целевом устройстве сделал бы нужный скрипт
4) На роутере в крон написал бы ssh -i закрытыйключ юзер@цель /полный/путь/к/скрипту

И никаких експектов не надо. Если ssh клиент в прошивке не понимает -i, поставьте взрослый клиент из пакета openssh.

mikypich
05-01-2009, 20:36
Я ссылаюсь на http://wl500g.info/showpost.php?p=91357&postcount=23

когда запускаю ./remotepcshutdown.sh то выдает-


./remotepcshutdown.sh
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected
[: ==: binary operator expected





В чем тут дело? Может кто подскажет?

у меня все работало пока я не выполнил команду
ipkg install bash sed grep coreutils wget libuclibc++
после этого посыпались эти
[: ==: binary operator expected
какой пакет гадит я не знаю, просто попытался сделать как написано тут:
http://wl500g.info/showthread.php?t=9947&page=4

откатился назад опять заработало

the
04-02-2009, 21:43
Пардон, братья, что пишу с опозданием более чем в год...

А какая процедура установки expect-mipsel-5.43.tar.gz (http://wl500g.info/attachment.php?attachmentid=1513&d=1179086522) (369.6 Кбайт) на роутер?

Внутри вижу


opt \
local \
bin \
include \
lib \
share \

al37919
14-03-2009, 20:32
просто развернуть

tar xvzf -C / expect-mipsel-5.43.tar.gz
/opt/local/bin можно дописать к PATH

/opt/local использую для приложений установленных не через автоматический ipkg

houligan
28-04-2009, 15:41
Возможно ктото устанавливал уже, поделитесь опытом.
во время ./configure пишел что не возможно найти tcl, хотя он установлен из стандарных утилит..

заранее спасибо.

vectorm
28-04-2009, 15:59
Возможно ктото устанавливал уже, поделитесь опытом.
во время ./configure пишел что не возможно найти tcl, хотя он установлен из стандарных утилит..

заранее спасибо.
Хакер почитываем? ;)
Там же написано, что надо установить переменную окружения.

houligan
28-04-2009, 16:09
Хакер почитываем? ;)
Ты знааал ;)
Тем не менее ни set, ни setenv не срабатывают..
при том что set выводит все переменные нормально.

al37919
28-04-2009, 16:12
переменная окружения --- export

я когда то выкладывал скомпиленный expect: http://wl500g.info/showthread.php?t=9292
а есть еще такая тема: http://wl500g.info/showthread.php?t=12492

houligan
03-05-2009, 18:40
У когонить получалось использовать этот скрипт для связи по ssh?



#!/bin/sh
. /opt/lib/expect/expect.lib.sh

expect_open -c ssh login@192.168.1.175
expect password
send_line mypass
expect_eol

expect_close

Собственно всё зависает на вводе пароля...
пробовал и expect assword и expect Password..

в чем может быть проблема?
Пусть прописан верно, тк скрипт коннектиться и ожидает ввода пароля.

fabvil
24-09-2009, 21:42
т.е. вроде такая страница есть, но каким должен быть url, чтобы вызвать корректное действие... ?
http://192.168.2.1/tools/restartmodem.htm показывает страницу:

Restarting...
The system is now restarting. Please wait.
и ничего не делает. Надо передавать параметры... А как их передать если метод POST?

Вроде с expect все как то проще получается:)

Может кто знает ответ?

mitay
12-12-2010, 09:48
скопировал эти скрпты, поменял адрес и логин\пароль, запускаю и
./expect_test: readonly: line 6: EXPECT_APP_PIPE_IN: is read only
ничего не гуглится, что за ошибка?
1.9.2.7-d-r2410

al37919
12-12-2010, 10:43
строго говоря, это скрипты на bash. Чтобы их запустить нужно либо установить bash из optware и поменять первую строку на #!/opt/bin/bash , либо в строках, которые начинаются с readonly просто убрать это слово. В остальном все работает замечательно.

mitay
12-12-2010, 11:54
да, спасибо, убрал readonly, дело пошло, но встало на строке ввода пароля

$ ./expect_test
./expect_test: line 6: background: not found
BCM96332 ADSL Router
Login: admin
Password:

после только CTRL+C
в чем проблема, что за background: not found?

al37919
12-12-2010, 14:27
покажите ваш expect_test, а также ответ устройства когда вы успешно логинитесь на него вручную.

mitay
12-12-2010, 15:14
expect_test:


#!/bin/sh

. /usr/local/sbin/mini-tools/expect.lib.sh
# цепляем библиотеку (ее код дан ниже)
expect_open -c telnet 192.168.1.1
# использование: expect_open [-c | -e <filename> ] <command> ....
#опция -с включает дублирование вывода на консоль
#опция -e включает дублирование вывода в <filename>
#без опций - вывода нет

expect Login
# ждем строку включающую в себя login - запрос имени пользователя

send_line admin
# отправляем строку с именем пользователя "admin" и перевод строки

expect_eol
# ждем перевод строки, который мы же и отправили ;)

expect Password:
send_line 123
expect_eol
expect_exact '>'
# ждем строку состоящую только из # - запрос от shell'а

expect_echo_start
# для примера - включение вывода на консоль с этого момента

send_line ifconfig
expect_eol

expect_capture_start
# начало захвата вывода в переменную $EXPECT_OUTPUT, очищает переменную

expect_eol
# ждем перевода строки, т.е. в $EXPECT_OUTPUT будет вывод от первого

echo "Modem is: $EXPECT_OUTPUT"
# date -s $EXPECT_OUTPUT
send_line logout
expect_eol
expect_close
# закрываем запущенный процесс (телнет)

пробовал send_line в кавычках и без



]$ telnet 192.168.1.1

Entering character mode
Escape character is '^]'.

BCM96332 ADSL Router
Login: admin
Password:
> logout

Bye bye. Have a nice day!!!
Connection closed by foreign host

al37919
12-12-2010, 18:27
Глобальных проблем не вижу, поэтому по мелочам.

Ругань на строку 6 в первом случае относится к строке с коммандой expect_open
Однако, в приведенном скрипте это строка 5, что немного странно

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

expect_exact '>'
может там в возвращаемой строке какой пробел затесался или невидимый китайский символ...

Можно предложить попробовать

expect '>'
либо вообще убрать эту строку, можно попробовать добавить паузу, напр. sleep 5

mitay
13-12-2010, 03:29
а не может быть что ругань идет на эту строку:
send_line 123
или та эту:
expect Password:
ведь пробельные строки и строки с комментариями отбрасываются, тогда эта как раз 6-я
кроме того, курсор мигает сразу после слова Password:<курсор>, т.е. переход на следующую строку не осуществляется, так и висит пока таймаут не истечет. т.е. как будто до expect_exact '>' дело не доходит
пробовал убирать expect_exact '>' и ставить sleep 5, менял '>' на '> ' - такая же реакция

провел эксперименты на дебиане, коннектился к довекоту, расставил echo "--mark--" по скрипту, история такая же, до пароля метка выводится, после метка не выводится, т.е. скрипт останавливается на вводе пароля.

al37919
13-12-2010, 07:24
для отладки можно после #!/bin/sh поставить set -x
А вообще, скорее всего дело в : после Password. Его надо убрать.

mitay
13-12-2010, 08:10
двоеточие не причем, за отладку спасибо!
попадает в бесконечный цикл в функции expect_handle_input ()
while true; do
пойду найду умную книшку по скриптам, буду разбираться

так уже bash использую
установил так: ipkg install bash
в скрипте пишу #!/bin/bash
те же грабли, счас буду разбираться, пока ясно одно, что условие [ ! -d /proc/$EXPECT_APP_ID ] всегда ложно, т.е. это каталог

al37919
13-12-2010, 08:34
все же советую попробовать исполнить это через bash. По bash книжек много, а вот по встроенному ash из busybox не очень. К тому же он обильно конфигурируется при сборке, так что не исключено, что какая то фича просто не включена в нашей прошивке. Если через один интерпретатор будет работать, через другой нет, задача упростится до "найди отличие".

Я разбирался с этим скриптом уже довольно давно --- не помню ньюансов, но по каким-то причинам остановился на решении с bash

mitay
13-12-2010, 11:35
злобный expect_eol приносил с собой строку Password, так что когда expect Password ждал слово Password, то уже ничего не дожидался, цикл-таймаут-цикл-таймаут...
удалил expect_eol после ввода логина и пароля и заработало,
принцип ясен, большое спасибо за помощь!

поспешил с выводами, эксперименты на дебиане с рор3-сервером принесли положительные плоды, но там пароль выводился на экран
на асусе потерпел фиаско, там пароль не выводится, а после send_line 123 программа ждет вывода 123, и зацикливается ((...

MrGalaxy
14-05-2011, 15:45
Как выполнить команду через telnet на подключённом к роутеру устройству, передав пароль в качестве параметра?

MrGalaxy
15-05-2011, 10:16
Спасибр автору за скрипт.
У меня заработало так (например, узнать состояние ADSL-соединения на модеме Huawei MT880):

#!/bin/sh

. /usr/local/bin/expect.lib.sh

expect_open telnet -l admin 192.168.1.1

expect Password
send_line 'пароль'
expect_eol
expect ">"
expect_echo_start
send_line "show wan adsl status"
expect_eol

expect_close
Почему-то на Хуавей-МТ880 telnet и без ключа -l тоже упорно входил, сразу требуя пароль. Имя вводить не нужно.

Совет: войдите сначала в телнет вручную и посмотрите, что там вообще выскакивает и требует ввода - какие символы, вопросы и т.д. и в соответствии с этим измените скрипт.

ЗЫ: cyrax, может упростите Вашу библиотеку, чтобы можно было всего-навсего передать команду телнет (как в моём случае) без наворотов со считыванием даты-времени? Мозг закипает при взгляде на этот скрипт...:eek:

joserg_2
13-06-2011, 17:30
Решили создать на wl500gpv2 web-сервер со ссылками на выполнение определенных команд в телнете (linux-команд).

Как эти ссылки можно написать? Выполнимо ли это со встроенным сервером в прошивке от энтузиастов?



Спасибо

as_lan
27-06-2011, 22:22
Привет,

да, давно не заходил сюда.......



Не хочет работать, жалуется в ответ

/myscript.sh: readonly: line 5: EXPECT_APP_PIPE_IN: is read only
5 линия в скрипте

expect_open telnet -l admin 192.168.1.1

Дир 320. Прошивка 1.9.2.7-d-r2624

2dfx
28-06-2011, 21:54
Являюсь владельцем модема cmotech 550pro.
Гадость отвратная, но можно настроить работу в режиме моста.
Очередное НО. После потери первого коннекта связь пропадает навсегда.

Выход из ситуации:
В файле для pppd убрать "persist"
Добавить "maxfail 15"

Само подключение вызывать след. скриптом:
#!/bin/sh
while true ; do
/usr/sbin/pppd file /tmp/ppp/ppp.conf
sleep 5
/usr/local/sbin/ppp-fail
sleep 20
done
exit 0


Файл /usr/local/sbin/ppp-fail:
#!/bin/sh
(sleep 2; \
echo -en "admin\r\n"; \
sleep 2; \
echo -en "password\r\n"; \
sleep 2; \
echo -en "reboot\r\n"; \
sleep 15) | telnet 192.168.0.1

Black_Ru
29-06-2011, 23:57
Можно сделать без expect



#!/bin/bash
(sleep 5; echo Mypassword; sleep 3; echo "reboot"; sleep 1) |
socat - EXEC:'ssh -l router 192.168.1.1',pty,setsid,ctty

Предварительно установив socat