我希望Perl仅在STDOUT不相同的情况下写入STDERR。例如,如果STDOUT和STDERR都将输出重定向到终端,那么我不希望打印STDERR。
考虑以下示例(outerr.pl):
#!/usr/bin/perl
use strict;
use warnings;
print STDOUT "Hello standard output!\n";
print STDERR "Hello standard error\n" if ($someMagicalFlag);
exit 0
现在考虑一下(这是我想要实现的目标):
bash $ outerr.pl
Hello standard output!
但是,如果我重定向到文件,我想得到:
bash $ outerr.pl > /dev/null
Hello standard error
和反过来相似:
bash $ outerr.pl 2> /dev/null
Hello standard output!
如果我将两个/ err重定向到相同的文件,则只显示out:
bash $ outerr.pl > foo.txt 2>&1
bash $ cat foo.txt
Hello standard output!
那么有没有办法评估/确定OUT和ERR是否指向相同的“事物”(描述符?)?
答案 0 :(得分:6)
在Unix风格的系统上,您应该能够:
my @stat_err = stat STDERR;
my @stat_out = stat STDOUT;
my $stderr_is_not_stdout = (($stat_err[0] != $stat_out[0]) ||
($stat_err[1] != $stat_out[1]));
但是这不适用于Windows,它没有真正的inode数字。它既给出了误报(认为它们不同时也是不同的)和假否定(认为它们不相同时就是相同的。)
答案 1 :(得分:4)
你可以(差不多)用-t:
来做到这一点-t STDERR
如果它是终端,则将为true,对于STDOUT也是如此。
这仍然不会告诉你什么终端,如果你重定向到同一个文件,你可能仍然可以得到这两个。
因此,如果
-t STDERR && ! (-t STDOUT) || -t STDOUT && !(-t STDERR)
或更短
-t STDOUT ^ -t STDERR # thanks to @mob
你知道你没事。
编辑:STDERR和STDOUT都是常规文件的解决方案:
汤姆克里斯蒂安森建议统计并比较dev和ino字段。这将在UNIX中工作,但正如@cjm指出的那样,而不是在Windows中。
如果您可以保证没有其他程序会写入该文件,您可以在Windows和UNIX中执行以下操作:
>>
将其中一个重定向到a
非空文件。