Home > Archive > Tcl > June 2007 > REG Expression in Expect { }
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
REG Expression in Expect { }
|
|
| Knilges 2007-06-27, 4:22 am |
| set lineterminationChar "$\""
#set lineterminationChar1 "^;"
expect {
-re $lineterminationChar {append output
$expect_out (buffer);exp_continue }
-re "^;" {append output
$expect_out(buffer);exp_continue }
eof {append output
$expect_out(buffer) }
}
puts $outputfile $output
set output {}
I am trying to have expect key on a regexp but I am doing something
wrong because it is not doing that it is simply filling up (buffer)
and then erroring out because it never reaches eof or something like
that...
the character I am trying to key on is a ; a the beginning of the line
(in fact it should be the only character in the line) or a " at the
end of the line.
This is data being received from a terminal from commands sent to it
from a command file. What I want to happen is:
first command from file sent,
line terminating with " is received capture and send to output file
repeats this until a line beginning with a ; is received and then look
for the next line in the command file and this is repeated until the
eof is recieved from the command file, which then closes everything
down.
Keith
| |
| Bezoar 2007-06-27, 4:22 am |
| On Jun 26, 3:13 pm, Knilges <knil...@hotmail.com> wrote:
> set lineterminationChar "$\""
> #set lineterminationChar1 "^;"
> expect {
> -re $lineterminationChar {append output
> $expect_out (buffer);exp_continue }
> -re "^;" {append output
> $expect_out(buffer);exp_continue }
> eof {append output
> $expect_out(buffer) }
> }
> puts $outputfile $output
> set output {}
>
> I am trying to have expect key on a regexp but I am doing something
> wrong because it is not doing that it is simply filling up (buffer)
> and then erroring out because it never reaches eof or something like
> that...
>
> the character I am trying to key on is a ; a the beginning of the line
> (in fact it should be the only character in the line) or a " at the
> end of the line.
>
> This is data being received from a terminal from commands sent to it
> from a command file. What I want to happen is:
> first command from file sent,
> line terminating with " is received capture and send to output file
> repeats this until a line beginning with a ; is received and then look
> for the next line in the command file and this is repeated until the
> eof is recieved from the command file, which then closes everything
> down.
>
> Keith
Keith :
You have a few problems. The definition of :
set lineterminationChar "$\""
is going to cause you trouble. By putting the $\" in
"" you are evaluating it so Tcl is looking for a variable
named $\". So at the very least you should do this instead
set lineterminationChar {[^\"]\"}
I tried to follow what you had written and it seemed the
best way to do this was to parse out the commands from
the file then run the commands. Like below. I hope it
does not confuse the issue but your explaination of what
you were working with was not entirely clear.
I assumed you were spawning a shell and running
shell commands. I made up a test commmand file where each
command outputs a single quote as shown. Hope this was
what you were trying to get to. If you try to run this
then you must change the commands in the cmdfile since it
is unlikely that you have the same set of files ;-). Note that
each command will issue a \" when it completes.
run like : process.exp cmdfile cmd.out
-----------cmdfile -------------------
echo "`ls -l sqltest.tcl` \"";
;
echo "`wc -l s.tcl`\""
echo "`wc -l sync.tcl`\""
echo "`wc -l tequilaSetClient.tcl`\""
echo "`wc -l tequilaWriteClient.tcl`\""
;
echo "`wc -c test.tcl`\""
echo "`wc -c tilebutton.tcl`\""
echo "`wc -c u.tcl`\""
;
----------End cmdfile ----------------
----------- output file ---------------
-rwxrwxr-x 1 carl carl 1806 Jun 8 17:17 sqltest.tcl
13 s.tcl
62 sync.tcl
10 tequilaSetClient.tcl
14 tequilaWriteClient.tcl
1317 test.tcl
2048 tilebutton.tcl
635 u.tcl
-------------- end output file ---------
------------ Start expect script ---------------
#!/bin/sh
# the next line restarts using wish \
exec /opt/usr/bin/tclsh8.5 "$0" ${1+"$@"}
#You explaination of the command file indicated that the commands
#may span more than one line
package require Expect;
# procedure to quickly get the commands out
# checks for blank lines and comments (lines that start with #
proc getcommands { file } {
set fd [ open $file "r" ]
set buffer [ read $fd ];
foreach cmd [ split $buffer "\n" ] {
if { [string length $cmd ] > 0 && [string first "\#" $cmd ] != 0 } {
lappend retlist $cmd
}
}
return $retlist;
}
# procedure to save in append mode any data
proc save { filename buffer {mode "a"} {perm 0666 } } {
if { [catch { open $filename $mode $perm } fd ] != 0 } {
puts "Unable to open file $filename in mode $mode: $fd"
return;
} else {
puts $fd "$buffer"
catch { close $fd }
}
}
# provide the command file as arg 1 and output file as arg 2
# on command line
set commandfile [lindex $argv 0 ]
set savefile [lindex $argv 1 ]
set commandlist [getcommands $commandfile ]
# make sure you have the comands
puts "commandlist:\n[join $commandlist \n ]"
set mypid [ spawn /bin/sh ] ; #what are you spawning?
# I will assume you are logged in and are running
# this script manually and do not need to login
set myspawnid $spawn_id;
set bad 0;
set done 0;
exp_internal 0; # set to one for extensive debug
log_user 1; # set to one to watch action
set prompt {sh-3.1\$ };
set outbuffer "" ;
# stop that pesky echoing shells echo the command
# so need to send a stty command to stop the damn thing
# from echoing back all the commands we send.
exp_send -i $myspawnid "stty -echo\r"
expect -i $myspawnid -re $prompt {;}
expect {
-i $myspawnid
-re $prompt {
# I assume I will not see prompt in ouput and that there
# is a prompt
# get next command off of the list
set command [ lindex $commandlist 0 ] ;
# remove current command from the list
set commandlist [lrange $commandlist 1 end ] ;
# when command is ; then save all output
if { [string equal [string trim $command ] ";" ] } {
send_user "saving buffer to $savefile"
save $savefile $outbuffer "a"
set outbuffer "" ; #clear it
# advance to next command
set command [ lindex $commandlist 0 ] ;
set commandlist [lrange $commandlist 1 end ] ;
}
# send the next command or break out of loop
if { [ string length $command ] != 0 } {
send_user "issuing command:$command\n"
exp_send -i $myspawnid "$command\r"
exp_continue;
}
}
-re {[^\"]*\"} {
#collect everything until a quote is found
# alway brace note if its possible for the prompt to show
# up in the output you can set a flag and use a separate
# buffer to store the output.
#open file and save output
send_user "At end of commands\n"
# note removing quote
append outbuffer "[string trim $expect_out(buffer) "\""]\n";
set readingmode 0; # now prompt recognized again.need this to
issue
# if you dont need or have a prompt then
send
# next command here. Most people have
prompt
exp_continue;
}
timeout {
puts "timeout"
exec kill -9 $mypid; # unix only
}
fullbuffer {
# incase result too big expect does have this special case
lappend outbuffer $expect_out(buffer);
exp_continue;
}
eof {
puts "Eof detected "
set done 1 ;
}
}
if { $bad || $done } {
set exitstatus [ exp_wait -i $myspawnid ];
catch { exp_close -i $myspawnid };
}
| |
| Glenn Jackman 2007-06-27, 7:12 pm |
| At 2007-06-26 11:44PM, "Bezoar" wrote:
> On Jun 26, 3:13 pm, Knilges <knil...@hotmail.com> wrote:
> Keith :
> You have a few problems. The definition of :
>
> set lineterminationChar "$\""
>
> is going to cause you trouble. By putting the $\" in
> "" you are evaluating it so Tcl is looking for a variable
> named $\". So at the very least you should do this instead
Actually, no. Tcl is not Perl. A backslash is not a valid variable
name for the $name style of variable substitution. See
http://www.tcl.tk/man/tcl8.4/TclCmd/Tcl.htm#M11
To find a line with a trailing double quote, you'd need
set quote_at_eol_regex {"$}
However, that may not be quite right for Expect which may consider the
regex $ as the end of string, so you may need:
set quote_at_eol_regex "\"\n"
or
set quote_at_eol_regex "\"\r\n"
Similarly, to find a line containing only a semicolon, you want one of
set only_semicolon_regex {^;$}
set only_semicolon_regex "\n;\n"
set only_semicolon_regex "\r\n;\r\n"
--
Glenn Jackman
"You can only be young once. But you can always be immature." -- Dave Barry
|
|
|
|
|