2010-10-18 47 views
4

this perldoc page这些流重定向如何工作?

  1. 要捕获一个命令的STDERR和STDOUT在一起:

    $output = `cmd 2>&1`;
  2. 要捕获一个命令的标准输出,但是却丢弃其STDERR:

    $output = `cmd 2>/dev/null`;
  3. 要捕获命令的STDERR,但放弃其STDOUT(订购在这里很重要):

    $output = `cmd 2>&1 1>/dev/null`;
  4. ,以便捕捉到STDERR但离开其STDOUT走出来交换命令的STDOUT和STDERR老STDERR:

    $output = `cmd 3>&1 1>&2 2>&3 3>&-`;

我不明白怎么3和4项工作,我不太确定我对1和2的理解是否正确。以下是我的理解。请纠正我错在哪里。

我知道012象征STDINSTDOUTSTDERR

  1. 重定向2比1,这样他们两人现在都使用相同的流(&逃脱1确保STDERR不会被重定向到一个名为1而不是文件)

  2. 重定向2(STDERR )到空流,以便它被丢弃

  3. 我不明白这一个。难道不应该只是

    $output = `cmd 1>/dev/null`;

    而且,如果目的是在STDOUT得到STDERR消息,不会1>/dev/null一切重定向到/dev/null

  4. 这里发生了什么事?什么是流3?它是否像一个临时变量?

+0

@skaffman - 为什么重新添加perl标签?提到perl并不是相关的问题。 – 2010-10-18 19:50:28

+0

@bemace:我的错误 – skaffman 2010-10-18 19:52:43

回答

3

真的,这一切都不是Perl的 - 所有这一切都是由你使用反引号操作符调用壳处理。所以你最好的阅读是man sh,或Shell chapter of the Unix standard

总之,虽然,对#4:

  • 3>&1:开放FD 3以指向标准输出当前指向。
  • 1>&2:重新打开stdout指向stderr当前指向的位置。
  • 2>&3:重新打开stderr指向FD 3当前指向的位置,这是stdout指向之前之前的步骤已完成。现在stdout和stderr已经成功交换了。
  • 3>&-:关闭FD 3因为它不再需要。
+0

重定向从左到右受到影响,是吗? – Lazer 2010-10-18 20:24:29

+0

@拉泽尔:没错。 – 2010-10-18 20:36:40

+0

@拉齐尔是的,他们是。该标准也是如此。 :) – hobbs 2010-10-18 21:54:08

-2

3.不需要。排序很重要,所以它摆脱了原来的标准输出,然后它将stderr移到标准输出。

4. 3只是另一个文件描述符,与第3个相同。大多数进程可以使用总共256个不同的文件描述符。

+0

“2>&1 1>/dev/null” - >“...然后它将stderr移到stdout”。你确定?它不是以相反的顺序发生吗? – Lazer 2010-10-18 19:51:09

+0

重定向从右到左进行。 – 2010-10-18 19:58:32

+0

@Ignacio:那么它在** 4 **中是如何工作的?这意味着3号流在打开之前就已经关闭了! – Lazer 2010-10-18 20:01:29

3

虽然记录在perldocs中,但重定向是所有标准的linux重定向。你正确理解1和2。

3)仅STDOUT通常由基本重定向(>)抓住,所以原来STDOUT必须被丢弃, STDERR必须发送到STDOUT。

4)cmd 3>&1 1>&2 2>&3 3>&-相当于

var tmp = STDOUT; 
STDOUT = STDERR; 
STDERR = tmp; 
delete tmp; 
3

通常情况下,我们有这样的:

1-->STDOUT 
2-->STDERR 

2>&1文件描述符fd2重定向到fd1

1-->STDOUT 
/
2./ 

2>/dev/null重定向到fd2/dev/null

1-->STDOUT 
2-->/dev/null 

2>&1 1>/dev/null重定向fd2fd1,然后重定向fd1/dev/null

/dev/null 
/
1./ STDOUT 
/
2./ 

3>&1 1>&2 2>&3 3>&-

  1. 第一指示一个新的FD 3到哪里 FD 1当前所指向(STDOUT) 。
  2. 然后重定向FD1到哪里FD2是 电流指示(STDERR),
  3. 然后重定向FD 2到哪里FD 3 当前指向(STDOUT)
  4. 然后关闭FD3(3> & - 表示关闭 文件描述符3)。

整个事情有效地互换fd1和fd2。 fd3充当临时变量。

1 --STDOUT 
X 
2 `-STDERR 

对IO重定向的详细信息,请参阅the docs