Thursday, October 30, 2008

Ужасные новости

Какой шторм сейчас в fedora-devel-list. Страсти кипят, шипят, как масло на сковородке. Настоящая буря в стакане.

Висение иксов на tty1 вместо tty7 это, безусловно, крушение всех надежд. Падение Геллы в бурлящий пролив Босфора. Некоторым, правда, кажется, что обсуждение этого больше похоже на мужественную борьбу за тень осла, но таких несознательных людей мы слушать не будем.

Dax Kelson выступает перед пританами. Чело его взволновано, руки дрожат:

This specific Linux behavior is well documented in hundreds of thousand of publications ranging from college text books, HOWTOs, Linux books sold in retail stores, blogs, forums, guides, and training manuals. Making a change invalidates all that published knowledge.

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

Пользователь fedora:

(закрывая лицо руками)
Погиб я! О бесчестные, что поменяли tty7 на tty1!
Ради богов,
Примите плащ мой, я бегу.
(убегает, рыдая)

Saturday, October 11, 2008

Capturing output of Expect [send] command

В кои то веки посреди груд папуасского мусора в зиване возник производственный вопрос. Соколов, конечно, умудрился максимально напустить тумана в том, что конкретно ему хотелось от Expect, хотя с поднятой им проблемой сталкиваются практически все новички в Expect, так что мы позволим себе здесь вышеприведенное обсуждение продолжить.

Правильно сформулированный вопрос стоит так: я посылаю с [send] текст и желаю получить ответ не просто поймав его посредством [expect], но желаю иметь этот output в переменной для моей-не-скажу-для-чего прихоти.

Короткий ответ на такой вопрос будет такой: см. на переменную expect_out, которую заполняет [expect]. Это обычный Tcl array. Лучше всего понять, как он заполняется, это написать

flush stdout
parray expect_out

Где нибудь в конце вашего диалога со spawn'еной программой. Для окончательно ясности, напишем 2 скрипта: 1-й на sh, который будет программкой с которой будет работать 2-й скрипт, написанный на Expect.

% cat foobar.sh
#!/bin/sh

printf "Please enter your name: "
read name

[ -z "$name" ] && {
  echo "For what such secretiveness?"
  exit 1
}

echo -- Thank you, $name

Все что сделает наш второй Expect-скрипт, -- это избавит вас от утомительной работы по введению имени, которое потребует foobar.sh.

% cat foobar-expect.tcl
#!/bin/sh
# -*-tcl-*- \
# the next line restarts using expect \
exec expect "$0" "$@"

set cmd ./foobar.sh
set timeout 5
if {[catch {
  spawn -noecho $cmd
} r]} {
  puts stderr "$argv0 error: $r"
  exit 1
}

log_file -noappend temp-file
expect "Please enter your name: "
set name "Jeeves"
#set name ""
exp_send "$name\n"
expect {
  -re "Thank.* ${name}\r\n$" { puts "-- Yes, sir." }
  timeout {
      send_user "timeout because there was no prompt\n"
      exit 1
  }
}

flush stdout
parray expect_out

set status [wait $spawn_id]
if {[lindex $status 2] == 0} {
  exit [lindex $status 3]
}

Теперь запустим foobar-expect.tcl, чтобы окончательно разобраться с expect_out:

% ./foobar-expect.tcl
Please enter your name: Jeeves
-- Thank you, Jeeves
-- Yes, sir.
expect_out(0,string) = Thank you, Jeeves

expect_out(buffer)   = Jeeves
-- Thank you, Jeeves

expect_out(spawn_id) = exp4

$expect_out(0,string) содержит именно то, что мы поймали командой [expect] после [exp_send]. Чтобы посмотреть на полный диалог, загляните в появившийся файл temp-file, создаваемый командой [log_file].