【问题标题】:Running external program in Perl without simultaneous output在 Perl 中运行外部程序而不同时输出
【发布时间】:2019-10-27 15:43:48
【问题描述】:

我有一个 Perl 脚本

for my $i (1..10) {
    print "How $i\n";
    sleep(1);
}

我想从另一个 perl 脚本运行它并捕获它的输出。我知道我可以使用 qx() 或反引号,但它们会在程序退出时同时返回所有输出。

但是,我想要的是在第二个脚本可用时立即打印第一个脚本的输出,即。对于示例代码,第一个脚本的输出从第二个脚本分十步打印出来,而不是一次打印。

我查看了this question 并将我的第二个脚本编写为

my $cmd = "perl a.pl";
open my $cmd_fh, "$cmd |";

while(<$cmd_fh>) {
    print "Received: $_\n";
    STDOUT->flush();
}

close $cmd_fh;

但是,输出仍在同时打印。我想知道如何完成这项工作?

【问题讨论】:

  • this post 中带有IPC::Run 的伪终端的简单而具体的示例。如果可用,还可以选择使用程序unbuffer;在链接页面上查看其他答案。

标签: perl pipe ipc


【解决方案1】:

子进程以 4 或 KiB 或 8 KiB 的块发送输出,而不是一次发送一行。 Perl 程序,像大多数程序一样,在换行时刷新 STDOUT,但仅在连接到终端时;否则,它们会完全缓冲输出。您可以将$| = 1; 添加到子级以禁用STDOUT 的缓冲。

如果你不能修改孩子,这样的程序可以通过使用伪 ttys 而不是管道来欺骗。见IPC::Run。 (在其文档中搜索“pty”。)

【讨论】:

  • 使用run \@cmdArr, '&gt;pty&gt;', sub { print "@_" } 解决了这个问题。但是,假设我还想将一个字符串作为输入传递给我正在运行的程序(程序提示用户输入),那么我应该如何修改这个语句?
  • 我试图实际运行的命令是ssh 命令。我试图传递的输入是远程登录的用户密码。我试过这个 - run \@cmdArr, \$sshpwd, '&gt;pty&gt;', sub { print "@_" } - 但这似乎不起作用,它仍然要求输入密码。
  • 我在这里找到了答案 - stackoverflow.com/questions/24454037/…。不要使用ssh 登录远程系统,而是使用sshpass
猜你喜欢
  • 2012-03-06
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 2017-08-08
  • 2018-06-19
相关资源
最近更新 更多