Gre*_*con 10
说你的R程序是
#! /usr/bin/env r
require(Hmisc)
cat(argv[1], "\n")
Run Code Online (Sandbox Code Playgroud)
结果令人惊讶的是:
$ ./prog.r foo
Loading required package: Hmisc
Loading required package: methods
Loading required package: survival
Loading required package: stats
Loading required package: utils
Loading required package: graphics
Loading required package: splines
Attaching package: 'Hmisc'
The following object(s) are masked from package:survival :
untangle.specials
The following object(s) are masked from package:base :
format.pval,
round.POSIXt,
trunc.POSIXt,
units
foo
从这里,您可以丢弃标准错误或将其与另一个流合并.
丢弃标准错误的一种方法是使用shell重定向2>/dev/null.这是一种通用机制,2是标准错误的文件描述符.例如:
#! /usr/bin/perl
use warnings;
use strict;
open my $command_out, "-|", "./prog.r foo 2>/dev/null"
or die "$0: could not start prog.r";
while (<$command_out>) {
print "got: $_";
}
Run Code Online (Sandbox Code Playgroud)
shell也会处理反引号或qx//表达式
#! /usr/bin/perl
use warnings;
use strict;
(my $command_out = `./prog.r foo 2>/dev/null`) =~ s/^/got: /mg;
print $command_out;
Run Code Online (Sandbox Code Playgroud)
并传递一个标量命令 system
#! /usr/bin/perl
use warnings;
use strict;
system("./prog.r foo 2>/dev/null") == 0
or warn "$0: prog.r exited " . ($? >>8);
Run Code Online (Sandbox Code Playgroud)
对于所有这些,输出是
$ ./prog.pl got: foo
但有时你不希望shell把你的肮脏手套放在你的命令上.也许它包含你不想处理转义的shell元字符或引号.这是一个安全的管道打开很有用:
#! /usr/bin/perl
use warnings;
use strict;
my $pid = open my $command_out, "-|";
die "$0: fork: $!" unless defined $pid;
if ($pid == 0) {
# child
open STDERR, ">", "/dev/null" or die "$0: open: $!";
exec "./prog.r", "foo & bar" or exit 1; # STDERR silent now
}
while (<$command_out>) {
print "got: $_";
}
close $command_out or warn "$0: prog.r exited " . ($? >> 8);
Run Code Online (Sandbox Code Playgroud)
打开"-|"叉子上的手柄并将孩子的标准输出连接到该手柄.例如fork,它向子节点返回0,向父节点返回非零进程标识符,或者在失败时返回未定义的值.
在孩子中,我们首先重定向STDERR到/dev/null然后用exec我们的R程序替换孩子.请注意,我们以列表形式传递命令以绕过shell:
如果LIST中有多个参数,或者LIST是一个具有多个值的数组,则使用LIST中的参数调用execvp(3).
因为我们不能再看到标准错误,所以明确close $command_out地检查孩子是否幸福地运行是很重要的.否则,你会得到一个令人费解的无声失败.
样品运行:
$ ./prog.pl got: foo & bar
STDERR成STDOUT要查看句柄上的标准错误,请2>&1改用,例如,
open my $command_out, "-|", "./prog.r foo 2>&1" or die;
Run Code Online (Sandbox Code Playgroud)
使用安全管道打开,dup标准输出上的标准错误:
if ($pid == 0) {
# child
open STDERR, ">&", \*STDOUT or die "$0: open: $!";
exec "./prog.r", "foo & bar" or die "$0: exec: $!";
}
Run Code Online (Sandbox Code Playgroud)
该open文件涵盖了这一点:
您也可以在Bourne shell传统中指定EXPR开头
>&,在这种情况下,字符串的其余部分被解释为要被欺骗的文件句柄(或文件描述符,如果是数字)的名称(如dup(2))并打开了.
尽管你可以通过这种方式看到标准错误,但最好还是检查孩子的退出状态close.
现在一切都到了$command_out:
got: Loading required package: Hmisc got: Loading required package: methods got: Loading required package: survival got: Loading required package: stats got: Loading required package: utils got: Loading required package: graphics got: Loading required package: splines got: got: Attaching package: 'Hmisc' got: got: got: The following object(s) are masked from package:survival : got: got: untangle.specials got: got: got: The following object(s) are masked from package:base : got: got: format.pval, got: round.POSIXt, got: trunc.POSIXt, got: units got: got: foo & bar