如果用Expect发多行命令

# 大概流程:
# spawn一个shell, 读取命令文件中的每一行: 跳过空行/打印comments/发送命令到shell并expect提示符.
# 有一些东西用来控制换行, 纯粹让输出更好看, 去掉它们之后其实没几行.

# 命令文件: 其实就是简单的shell脚本, 只不过可以包含切换用户, 切换shell以及之后的命令

    my $ps1 = 'Regular Expression';
    
    my $exp = new Expect;
    #$exp->debug(1);
    #$exp->raw_pty(0);
    $exp->spawn("/bin/ksh") or die "Cannot spawn @_: $!\n";
    $exp->expect(undef, '-re', $ps1);
    
    open(SCRIPT, "<", $target_file) or die "Cannot open file, $!\n";
    
    # $each_line keeps one line in each loop

    # $print_new_line determines the "\n" before printing a non-command

    my ($each_line, $print_new_line) = ('', 'true');
    
    # Retrieve one line each time, print non-cmd, or send cmd and expect result
    while ($each_line = <SCRIPT>) {
        # parse empty line and whole-line comments
        if ($each_line =~ /^\s*$/ || $each_line =~ /^\s*\#/) {
            ($print_new_line eq 'true') ? (print "\n$each_line") : (print $each_line);
            $print_new_line = 'false';
            next;
        }
        
        $print_new_line = 'false';
        
        sleep 1;
        $exp->send("$each_line");
        
        # wait forever
        $exp->expect(undef,
                     [ qr/^Password:/,   sub { my $self = shift;
                                               $self->send("$passwd\n");
                                               exp_continue; } ],
                     [ qr/xxxx: Sorry/i, sub { exit 98;      } ],
                     [ qr/\[yes\/no\]/i, sub { my $self = shift;
                                               $self->send_slow(1, "yes\n");
                                               exp_continue; } ],
                     [ qr/$ps1/,         sub { $print_new_line = 'false'; } ],
                    );
    }
    
    close SCRIPT;


# 尽量在命令中指定username, 灵活性更高

# 小提示: 隐藏输入echo, 可以融入expect中
#system "stty -echo";
#chomp(my $passwd = <STDIN>);
#print "\n";
#system "stty echo";

# 自己揣摩吧

收下了,非常非常感谢!

我遇到跟你的情况相似,又不一样。

我是要telnet 到服务器里,向注册到服务器的语音网关,发送命令,有几百个网关。

而且命令,都不一样。不是现成的。要用正则得出命令,现在,正则是得结果了。连起来执行,就不行了。
只要你有办法连到一台..自然就可以连到其他台..要把连结与下指令分成两个部分去执行....

Expect的exp前面可以用个while(1) 包起来...

或for(my $i =0; $i<@commansize ; $i++)

这样子就可以在exp中写你要match的prompt与一些例外状况...并执行任意数量命令..
我的实现方法是,把所有命令,放在到一个文件里。一行,就是一个命令。然后,用
while(my $cmd=<FH> ){
    send($cmd);
{