我在一个示例脚本中找到了它, 然后我从谷歌搜索并找到以下单词,
请注意,您不能简单地将STDERR打开为Perl中STDOUT的副本 程序,并避免调用Shell进行重定向。这不是 工作:
open(STDERR, ">&STDOUT");
这失败,因为open()使STDERR转到STDOUT所在的位置 open()的时间。反引号然后使STDOUT转到字符串,但是 请勿更改STDERR(仍然使用旧的STDOUT)。
现在我很困惑。 open(STDERR, ">&STDOUT");
的确切含义是什么?
答案 0 :(得分:5)
在通话中,&
处于>&
模式下
open STDERR, ">&STDOUT"; # or: open STDERR, ">&", \*STDOUT
第一个给定的文件句柄成为第二个文件句柄的副本。请参见open和man 2 dup2
,因为这是通过dup2
syscall进行的。该符号遵循外壳程序的I/O redirection。
由于此处存在第一个文件句柄(STDERR
)†,因此它首先被关闭。
结果是打印到STDERR
的位置将移至STDOUT
进行之前的位置,而原始STDERR
的副作用将被关闭。
这是合法的,不会导致错误,但是并不是通常重定向STDERR
的好方法-之后,我们将无法再恢复STDERR
。有关如何重定向STDERR
的信息,请参见open。
注释的其余部分显然是指这样一种情况:在{{1}之后使用反引号(请参见qx)将执行的命令的STDOUT
重定向到程序。 }。所有这些似乎都涉及以这种方式将open
重定向到STDERR
的想法。
A,STDOUT
是由STDERR
呼叫转到open
所要到达的地方而产生的,不会被反引号重定向,因此仍然会“出现”。就我而言,打印到STDOUT
的打印在终端上结束,因为我看到警告(STDERR
),
ls: cannot access...
(与perl -we'open STDERR, ">&STDOUT"; $out = qx(ls no_such)'
不同)。显式打印到perl -we'$out = qx(ls no_such 2>&1)'
的打印内容也以STDERR
的身份发送到终端(添加此类打印并将输出重定向到文件以查看)。
这可能是可以预期的,因为STDOUT
对文件句柄进行了复制,因此“新”文件(以前的&
)仍然位于STDERR
的位置正要去终点站。在这种情况下当然是意料之外的,因此是错误的。
† UNIX中的每个程序都使用文件描述符STDOUT
,{{}连接到标准流stdin
,stdout
和stderr
。 1}}和0
。然后在Perl程序中,我们为这些文件准备好了文件句柄,例如1
(对于fd 2)。
一些有关在Shell中操作文件描述符的有用文章:
答案 1 :(得分:2)
基本上是dup2(fileno(STDOUT), fileno(STDERR))
。请参见系统的dup2
手册页。
简而言之,它在系统级别将STDERR
与STDOUT
相同的流相关联。执行命令后,写入任一内容都与更改之前写入STDOUT
相同。
除非有人对STDOUT或STDERR感到困惑,它等同于shell命令
exec 2>&1