【问题标题】:Spawn Expect from a perl thread从 perl 线程生成 Expect
【发布时间】:2019-06-13 14:01:54
【问题描述】:

我正在编写一个脚本,该脚本需要定期(每 5 分钟)生成一个 Expect 进程来完成一些工作。下面是我拥有的生成 Expect 进程并完成一些工作的代码。脚本的主进程一直在做一些其他的工作,例如它可能等待用户输入,因为我在一个线程中调用这个函数'spawn_expect',每5分钟调用一次,但问题是Expect 没有按预期工作。

但是,如果我用另一个进程替换线程,也就是说,如果我 fork 并让一个进程负责生成 Expect,而另一个进程完成脚本的主要工作(例如在提示符处等待),那么 Expect 工作正常.

我的问题是有可能产生一个线程期望进程吗?我必须求助于使用流程来完成这项工作吗?谢谢!

sub spawn_expect {
    my $expect = Expect->spawn($release_config{kinit_exec});
    my $position = $expect->expect(10,
                    [qr/Password.*: /, sub {my $fh = shift; print $fh "password\n";}],
                    [timeout => sub {print "Timed out";}]);
    # if this function is run via a process, $position is defined, if it is run via a thread, it is not defined                         
    ...
 }

【问题讨论】:

  • 你能澄清一下:为什么这需要通过线程进行? (目的是什么——你打算在另一个线程中对$position 做某事吗?)你是什么意思“未定义”——在另一个线程中?
  • @zdim 这需要通过线程或另一个单独的进程进行的原因是因为我希望主进程做一些其他工作,包括从用户那里获取输入和做一些其他事情,所以我需要始终响应输入。这迫使我使用单独的线程/进程来使用 Expect 执行此定期工作。通过 $position 未定义我的意思是期望无法匹配密码。它不被任何其他线程使用(基本上它是一个 kinit renew 循环,通过 Expect 非常周期性的间隔提供密码)
  • 好的,谢谢。那么你可以很好地 fork 并完成它,但问题仍然是为什么 Expect 不在线程中做它的事情。

标签: multithreading perl expect.pm


【解决方案1】:

创建Expect 对象beforehand(不在线程内)并将其传递给线程

my $exp = Expect->spawn( ... );
$exp->raw_pty(1);
$exp->log_stdout(0);

my ($thr) = threads->create(\&login, $exp);
my @res = $thr->join();    
# ...

sub login {
    my $exp = shift;
    my $position = $exp->expect( ... );
    # ...
}

我使用多个线程进行了测试,其中一个使用Expect 和自定义测试脚本并将脚本的输出返回到主线程。让我知道我是否应该发布这些(短)程序。

Expect 对象在线程内创建时,它对我来说也失败了。我的猜测是,在这种情况下,它无法像正常那样设置它的 pty。

鉴于评论中的澄清,我会使用 fork 来完成这项工作。

【讨论】:

    猜你喜欢
    • 2020-02-11
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多