我正在尝试编写一个脚本,该脚本使用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将控制字符传递给进程?
答案 0 :(得分:1)
您正在搜索的字符转义是特定于Perl正则表达式。为了您的目的,我建议您通过ctrl-M
和ctrl-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