Subject: | Expect gets the wrong position-index. |
Hi,
I encountered a weird case.
I sent the somewhat long command with the below line to check two files size difference.
$exp->send(q| perl -e 'if ($o = -s "/etc/hosts.allow") { print "O $o " } if ($b = -s "/etc/hosts.allow.bak.20150527") { print "B $b" } print "\n";' | . "\
n");
After that I tried to collect before part of the last expect() call with $exp->before();
some severs work well, but some servers curiously do not work.
The following is the debbuggin message from $exp->exp_internal(1) on.
Show quoted text
------------------- cut here ---------------------------------------------------
handle id(5): Does ` perl -e \'if ($o = -s \"/etc/hosts.allow\") { print \"O $ \ro \" } if ($b = -s \"/etc/hosts.allow.bak.20150527\") { print \"B $b\" } print \"\\n\";\' \r \r\nO 2709 B 2674\r\n\033]0;admin@file1:~\007[admin@file1 ~]$ '
match:
pattern #1: -re `(?^:[\\$%#>\\]] $)'? YES!!
Before match string: ` perl -e \'if ($o = -s \"/etc/hosts.allow\") { print \"O '
Match string: `$ '
After match string: `\ro \" } if ($b = -s \"/etc/hosts.allow.bak.20150527\") { print \"B $b\" } print \"\\n\";\' \r \r\nO 2709 B 2674\r\n\033]0;admin@file1:~\007[admin@file1 ~]$ '
Matchlist: ()
handle id(5): Does ` perl -e \'if ($o = -s \"/etc/hosts.allow\") { pr\r\000<~]$ perl -e \'if ($o = -s \"/etc/hosts.allow\") { pri \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bnt \"O $o \" } if ($b = -s \r\000\r\000<\"/etc/hosts.allow\") { print \"O $o \" } if ($b = -s \" \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b/etc/hosts.allow.bak.2015\r\000\r\000<t \"O $o \" } if ($b = -s \"/etc/hosts.allow.bak.20150 \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b527\") { print \"B $b\" } pr\r\000\r\000<etc/hosts.allow.bak.20150527\") { print \"B $b\" } pri \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bnt \"\\n\";\' \r\nO 4842 B 4842\r\n[admin@web24 ~]$ '
match:
pattern #1: -re `(?^:[\\$%#>\\]] $)'? YES!!
Before match string: ` perl -e \'if ($o = -s \"/etc/hosts.allow\") { pr\r\000<~]'
Match string: `$ '
After match string: ` perl -e \'if ($o = -s \"/etc/hosts.allow\") { pri \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bnt \"O $o \" } if ($b = -s \r\000\r\000<\"/etc/hosts.allow\") { print \"O $o \" } if ($b = -s \" \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b/etc/hosts.allow.bak.2015\r\000\r\000<t \"O $o \" } if ($b = -s \"/etc/hosts.allow.bak.20150 \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b527\") { print \"B $b\" } pr\r\000\r\000<etc/hosts.allow.bak.20150527\") { print \"B $b\" } pri \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bnt \"\\n\";\' \r\nO 4842 B 4842\r\n[admin@web24 ~]$ '
Matchlist: ()
------------------- cut here ---------------------------------------------------
As you can see, I tried to wait command prompt but index funtion( https://metacpan.org/source/SZABGAB/Expect-1.32/lib/Expect.pm#L739 ) is getting the wrong index in the middle of sent command.(I don't know why and where characters like \b, \r, \000 come from)
because index function ignores prompt regex's the end of line anchor.
So I patched the code as follow to get position index when matching regex.
After this patch, Expect.pm works well as I expected.
--- Expect.pm_ 2015-05-28 17:22:18.604195460 +0900
+++ Expect.pm 2015-05-28 19:00:01.827230946 +0900
@@ -670,6 +670,8 @@
my $after;
my $match;
my @matchlist;
+ my $match_index;
+ my @matchlist_index;
# Set the last loop time to now for time comparisons at end of loop.
my $start_loop_time = time();
@@ -761,16 +763,19 @@
if ($Expect::Multiline_Matching) {
@matchlist =
( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/m);
+ @matchlist_index = ( $-[0] );
} else {
@matchlist =
( ${*$exp}{exp_Accum} =~ m/($pattern->[2])/);
+ @matchlist_index = ( $-[0] );
}
if (@matchlist) {
# Matching regexp
$match = shift @matchlist;
- my $start = index ${*$exp}{exp_Accum}, $match;
- die 'The match could not be found' if $start == -1;
+ $match_index = shift @matchlist_index;
+
+ my $start = $match_index;
$before = substr ${*$exp}{exp_Accum}, 0, $start;
$after = substr ${*$exp}{exp_Accum}, $start + length($match);