简体   繁体   English

IPC :: Open3并确定孩子是否在等待输入

[英]IPC::Open3 and determining if child is waiting for input

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
}

The above code is part of a script I am writing which needs to run another script (called child). 上面的代码是我正在编写的脚本的一部分,需要运行另一个脚本(称为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) 根据/ var / tmp中是否存在cookie文件(两个脚本都写在CentOS5 / perl 5.8.8上),孩子可能会也可能不会提示输入

I need to determine if and when the child is waiting for input, so that the parent can pass input from STDIN of parent. 我需要确定孩子是否以及何时等待输入,以便父母可以从父母的STDIN传递输入。 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. 我还需要使用open3打开子进程,因为我需要父进程传递Perl :: Critic的残酷(严重性1)检查。

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. 我包含了评论,因为当cookie文件已经设置好后,我至少可以让父母正确地调用孩子,因为孩子在这种情况下不等待输入。

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. 我发现的一个例子使用了strace( http://www.perlmonks.org/?node_id=964971 ),我觉得这可能对我想做的事情来说太复杂了。

Any links to guide me will be greatly appreciated. 任何指导我的链接将不胜感激。

You can check if there's space in the pipe (using select ). 您可以检查管道中是否有空间(使用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. 我认为你应该探索其他途径。


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. 在我看来,只有在满足与参数无关的某些条件时才从STDIN读取的程序将提供一个提示,指示它正在等待输入。 If that's the case, one could use Expect to launch and control the child program. 如果是这种情况,可以使用Expect来启动和控制子程序。

But the simplest solution would be to write the data to STDIN unconditionally. 但最简单的解决方案是无条件地将数据写入STDIN。 Implementing this using IPC::Open3 is very complicated [1] , so I recommend switching to IPC::Run3 (simpler) or IPC::Run (more flexible). 使用IPC :: Open3实现这一点非常复杂[1] ,因此我建议切换到IPC :: Run3 (更简单)或IPC :: Run (更灵活)。

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

or 要么

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

  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. 当你同时写入孩子的STDIN并从孩子的STDOUT读取时,你需要使用select (或其他东西)来避免死锁。 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是非常低级别的,并不适合你,而处理这个是IPC :: Run3和IPC :: Run raison d'être。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM