IPC::Open3 并确定孩子是否正在等待输入 [英] IPC::Open3 and determining if child is waiting for input

查看:45
本文介绍了IPC::Open3 并确定孩子是否正在等待输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

sub run_command
{
    my $COMMAND         = shift;
    my @OUTPUT;
    my %CMD             = {};

    $CMD{pid}           = open3(my $CH_IN, my $CH_OUT, my $CH_ERR, $COMMAND);
    $CMD{_STDIN}        = $CH_IN;
    $CMD{_STDOUT}       = $CH_OUT;
    $CMD{_STDERR}       = $CH_ERR;

    my $line            = readline $CMD{_STDOUT};
    print $line;

#    open my $CMDPROC, q{-|}, $COMMAND   or return;
#    foreach (<$CMDPROC>)
#    {
#        push @OUTPUT, "$ARG";
#    }
    close $CMDPROC                      or return;

    return @OUTPUT
}

上面的代码是我正在编写的脚本的一部分,它需要运行另一个脚本(称为子脚本).孩子可能会也可能不会提示输入,这取决于/var/tmp 中是否存在 cookie 文件(两个脚本都是在 CentOS5/perl 5.8.8 上编写的)

The above code is part of a script I am writing which needs to run another script (called child). The child may or may not prompt for input, depending on the presence of a cookie file in /var/tmp (both scripts written on CentOS5 / perl 5.8.8)

我需要确定子进程是否以及何时等待输入,以便父进程可以从父进程的 STDIN 传递输入.我还需要使用 open3 打开子进程,因为我需要父进程通过 Perl::Critic 的残酷(严重性 1)检查.

I need to determine if and when the child is waiting for input, so that the parent can pass input from STDIN of parent. I also need to use open3 to open the child process, as I need for parent to pass the brutal (Severity 1) check of Perl::Critic.

我包含了注释,因为当 cookie 文件已经设置时,我至少可以让父级正确调用子级,因为在这种情况下子级不会等待输入.

I included the comments, because when the cookie file is already set, I can at least get parent to call child properly since child doesn't wait for input in that case.

我已经四处检查,试图找到有关如何确定孩子是否正在等待输入的示例.我发现的一个例子使用了 strace (http://www.perlmonks.org/?node_id=964971) 并且我觉得这对于我想要做的事情来说可能太复杂了.

I've checked around trying to find examples of how to determine if the child is waiting for input. The one example I found used strace (http://www.perlmonks.org/?node_id=964971) and I feel as though that might be too complex for what I am trying to do.

任何指导我的链接将不胜感激.

Any links to guide me will be greatly appreciated.

推荐答案

您可以检查管道中是否有空间(使用 选择).您甚至可以检查管道中有多少可用空间.但是,我从未听说过能够检查线程是否在等待从管道读取时被阻塞.我认为你应该探索其他途径.

You can check if there's space in the pipe (using select). You can even check how much space is available in the pipe. However, I've never heard of the ability to check if a thread is blocked waiting to read from the pipe. I think you should explore other avenues.

在我看来,只有在满足与参数无关的某些条件时才从 STDIN 读取的程序会提供提示,表明它正在等待输入.如果是这种情况,可以使用 Expect 来启动和控制子程序.

It seems to me that a program that only reads from STDIN when certain conditions unrelated to arguments are met would provide a prompt indicating it's waiting for input. If that's the case, one could use Expect to launch and control the child program.

但最简单的解决方案是无条件地将数据写入 STDIN.使用 IPC::Open3 实现这个非常复杂[1],所以我建议切换到 IPC::Run3(更简单)或 IPC::Run(更灵活).

But the simplest solution would be to write the data to STDIN unconditionally. Implementing this using IPC::Open3 is very complicated[1], so I recommend switching to IPC::Run3 (simpler) or IPC::Run (more flexible).

# Capture's child's STDERR
run3 [ $prog, @args ], \$text_for_stdin, \my $text_from_stdout, \my $text_from_stderr;

# Inherits parent's STDERR
run3 [ $prog, @args ], \$text_for_stdin, \my $text_from_stdout;

<小时>

  1. 当您同时写入孩子的 STDIN 并从孩子的 STDOUT 读取时,您需要使用 select(或其他东西)来避免死锁.IPC::Open3 的级别非常低,不会为您执行此操作,而处理此问题的是 IPC::Run3 和 IPC::Run 存在的理由.
  1. When you both write to the child's STDIN and read from the child's STDOUT, you need to use select (or something else) to avoid deadlocks. IPC::Open3 is very low level and doesn't do this for you, whereas handling this are IPC::Run3 and IPC::Run raison d'être.

这篇关于IPC::Open3 并确定孩子是否正在等待输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆