我正在尝试编写一个脚本,它使用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用于表示控制字符;下面的字符决定构造的值。例如,\cA的值是chr(1),cb的值是chr(2),等等,血淋淋的细节在perlop中的Regexp类操作符中。对于ASCII和EBCDIC平台来说,chr(1)等意味着什么的完整列表是在perlebcdic中的操作符差异。
这就是我在运行脚本时得到的结果,它强烈地表明控制字符没有被正确地传递到子进程,而且可能根本没有被传递。
% perl bash.pl
bash-4.4$ echo hi
hi
bash-4.4$ okay done!这里发生了什么事?如何使用Expect.pm将控制字符传递给进程?
发布于 2016-12-21 06:33:20
您正在搜索的字符转义是Perl regex特有的。为了您的目的,我建议您将hex value传递给ctrl-M和ctrl-P。
$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 newlinehttps://stackoverflow.com/questions/41256133
复制相似问题