Perl Expect.pm将控制字符发送到子进程

时间:2016-12-21 06:02:13

标签: perl

我正在尝试编写一个脚本,该脚本使用bash行编辑器来调用先前输入的命令。这是我尝试自动化的简单会话。

$ bash --norc --noprofile
bash4.4$ echo hi
hi
bash4.4$
然后输入' ^ P ^ M'

bash4.4$ echo hi
hi

这是我第一次使用CPAN上的Expect.pm模块编写脚本。在调用行编辑器时,两个sleep 1用于防止竞争条件的可能性,因为我不确定perl在发生这种情况时会发现什么。

#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use autodie;
use Expect;

my $timeout = 10;

my $exp = Expect->new();

$exp->spawn('bash --norc --noprofile');

# wait for first prompt
$exp->expect($timeout, '$ ');
# send echo hi
$exp->send("echo hi\n");
# wait for prompt again
$exp->expect($timeout, '$ ');
# use history recall ^P, then send ^M
sleep 1;
$exp->send("\cp\cm");
sleep 1;
print "okay done!\n";

直到我点击"\cp\cm"(我还试过"\cP\cM")。根据perl文档,\cX引入了ASCII控制字符。 (http://perldoc.perl.org/perlrebackslash.html#Character-Escapes

  

控制字符\ c用于表示控制字符;该   \ c后面的字符确定构造的值。对于   例如,\ cA的值是chr(1),\ cb的值是chr(2),   血淋淋的细节在perlop的Regexp Quote-Like Operators中。一个   对于ASCII和EBCDIC,chr(1)等的完整列表   平台在perlebcdic中属于操作员差异。

这是我在运行脚本时实际获得的内容,强烈建议控制字符不会正确传递到子进程,并且可能根本没有传递。

% perl bash.pl
bash-4.4$ echo hi
hi
bash-4.4$ okay done!

这里发生了什么?如何使用Expect.pm将控制字符传递给进程?

1 个答案:

答案 0 :(得分:1)

您正在搜索的字符转义是特定于Perl正则表达式。为了您的目的,我建议您通过ctrl-Mctrl-P的{​​{3}}。

$exp->send("\x10"); # ctrl+P

$exp->send("\x0D"); # ctrl+M

更新(测试):

$exp->send("\x10"); # ctrl+P
$exp->send("\n"); # send newline
sleep 2;

# wait for prompt
$exp->expect($timeout, '$ ');

$exp->send("\x0D"); # ctrl+M
$exp->send("\n"); # send newline