我有一个简单的perl脚本:
#!/usr/bin/env perl
use strict;
use Data::Dumper;
use utf8;
binmode( STDOUT, ":utf8" );
$|++;
my $localBookmarks = {
a => "local bookmark A",
b => "local bookmark B",
c => "local bookmark C",
};
print Dumper $localBookmarks;
my $remoteBookmarks = getRemoteBookmarks();
print Dumper $remoteBookmarks;
print "choose a bookmark: ";
my $answer = <STDIN>;
print "You want: $answer";
# process $answer...
sub getRemoteBookmarks
{
# Net::SSH::Perl connection; exec command; parse it; return it
# lets just simulate this
sleep( 5 );
return { d => "remote bookmark D", e => "remote bookmark E" };
}
输出结果为:
$ perl test.pl
$VAR1 = {
'b' => 'local bookmark B',
'a' => 'local bookmark A',
'c' => 'local bookmark C'
};
$VAR1 = {
'd' => 'remote bookmark D',
'e' => 'remote bookmark E'
};
choose a bookmark:
当然print Dumper $localBookmarks
之后会有一个沉默5秒钟。
在等待&#34;远程书签&#34;时,是否可以在打印&#34;本地书签&#34;后立即阅读<STDIN>
?如果我知道这次我需要本地书签(我不必等待几秒钟下载)。否则,当&#34;远程书签&#34;下载后,应终止当前<STDIN>
,打印下载的书签,并且 - 再次 - 在底部应该有<STDIN>
。这可能与perl有关吗?
答案 0 :(得分:3)
有很多方法可以做到这一点。一个更明显的方法是生成一个线程来进行远程工作,并且在您从STDIN读取之后,并且假设您无法在那里找到答案,请加入该线程(以确保它的顺序)完成)并检查那里。该线程需要完成actions
中已有的所有操作,并删除&#34;选择书签&#34; line(通常打印getRemoteBookmarks
就足够了),打印出新组的翻转器,并打印出新的&#34;选择一个书签&#34;条目。
如果已经做出选择,在线程之间共享变量等等,那么阻止线程打印任何东西需要一些额外的修复,但这是一般的想法。
另一种选择是通过事件处理来处理这个问题。您基本上同时拥有输入(使用Term::ReadLine中的事件处理 - 请参阅Term::ReadLine::Event了解如何使用各种事件模块执行此操作)以及您的ssh同时进行。这避免了一些线程共享等等,因为一切都发生在同一个线程中。
无论哪种方式,你的脚本都会变得简单得多,你可能真的会更好地打印出来&#34;收集信息,请等待&#34;在开始时,收集本地和远程的所有选项,然后打印出选项。从成本/收益的角度来看,就是这样。
祝你好运。答案 1 :(得分:2)
这是一个使用IPC::Open3
打开读取远程书签的单个子进程的简单示例。当孩子完成后,它会将书签存储在一个文件中(另一种方法是使用线程,管道或文件句柄进行通信,但我认为这会使程序稍微复杂化)。当子进程终止时,父进程将收到CHLD
信号,这将导致父进程退出其输入循环并从磁盘读取远程书签。然后父级重新进入输入循环:
use feature qw(say);
use strict;
use warnings;
use Data::Dumper;
use IPC::Open3;
use Symbol qw(gensym);
use Storable qw(retrieve);
local $SIG{CHLD} = sub {
die "\nBackground process finished..\n";
};
my $child1 = start_reading_remote_bookmarks( );
my $local_bookmarks = {
a => "local bookmark A",
b => "local bookmark B",
c => "local bookmark C",
};
print Dumper $local_bookmarks;
eval {
run_input_loop();
};
if ($@) {
print "\n";
my $remote_bookmarks = retrieve('bookmarks.dat');
print Dumper $remote_bookmarks;
run_input_loop();
}
sub run_input_loop {
while (1) {
print "Choose a bookmark: ";
chomp(my $answer = <STDIN>);
say "You want: $answer";
# process $answer...
}
}
sub start_reading_remote_bookmarks {
my $cmd = 'get_bookmarks.pl';
my $cherr = gensym;
my $pid = open3( my $chin, my $chout, $cherr, $cmd );
return { pid => $pid, kid_in => $chin, kid_out => $chout, kid_err => $cherr };
}
其中get_bookmarks.pl
是
use strict;
use warnings;
use Storable qw(store);
sleep 5;
my $fn = 'bookmarks.dat';
store { d => "remote bookmark D", e => "remote bookmark E" }, $fn;