shell 这些流重定向是如何工作的?

lc8prwob  于 2023-05-29  发布在  Shell
关注(0)|答案(5)|浏览(170)

从这个perldoc页面
1.要同时捕获命令的STDERR和STDOUT,请执行以下操作:

$output = `cmd 2>&1`;

1.要捕获命令的STDOUT但放弃其STDERR,请执行以下操作:

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

1.要捕获命令的STDERR但丢弃其STDOUT(这里的顺序很重要),请执行以下操作:

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

1.交换命令的STDOUT和STDERR以捕获STDERR,但保留其STDOUT以输出旧的STDERR:

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

我不明白3和4是如何工作的,我也不太确定我对1和2的理解是正确的。下面是我理解的。请纠正我的错误。
我知道012象征着STDINSTDOUTSTDERR
1.将2重定向到1,这样它们现在都使用相同的流(&转义了1,以确保STDERR不会被重定向到名为1的文件)
1.将2(STDERR)重定向到空流,以便丢弃它
1.我不明白这个。难道不应该

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

此外,如果目标是在STDOUT上获取STDERR消息,那么1>/dev/null不会将所有内容重定向到/dev/null吗?
1.这是怎么回事?什么是stream 3?它是一个临时变量吗?

ioekq8ef

ioekq8ef1#

实际上,这些都不是Perl --所有这些都是由您使用反引号操作符调用的shell处理的。所以你最好的阅读是man sh,或者Unix标准的Shell章节。
简而言之,对于#4:

  • 3>&1:打开FD 3以指向stdout当前指向的位置。
  • 1>&2:重新打开stdout以指向stderr当前所指向的位置。
  • 2>&3:重新打开stderr指向FD 3当前指向的位置,也就是stdout在上一步完成之前 * 指向的位置。现在stdout和stderr已经成功交换了。
  • 3>&-:关闭FD 3,因为不再需要它。
qcuzuvrc

qcuzuvrc2#

虽然在perldocs中有文档说明,但重定向是所有标准的linux重定向。1、正确理解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;
2g32fytz

2g32fytz3#

通常我们有这个:

1-->STDOUT
2-->STDERR

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

1-->STDOUT
   /
2./

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

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

2>&1 1>/dev/nullfd2重定向到fd1,然后将fd1重定向到/dev/null

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

3>&1 1>&2 2>&3 3>&-
1.首先将新的fd 3引导到fd 1当前指向的任何地方(STDOUT)。
1.然后将fd 1重定向到fd 2当前指向的任何地方(STDERR),
1.然后将fd 2重定向到fd 3当前指向的任何位置(STDOUT)
1.则关闭FD 3(3>&-表示关闭文件描述符3)。
整个过程有效地交换了fd 1和fd 2。FD 3充当临时变量。
有关IO重定向的详细信息,请参阅the docs

noj0wjuj

noj0wjuj4#

重定向从左到右进行评估。下面是一个跟踪表:

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

| | 1(标准输出)|2(标准错误)|3|
| - -----|- -----|- -----|- -----|
| | 一个|2||
| 3>&1|一个|2|一个|
| 1>&2| 2| 2|一个|
| 2>&3| 2| 1*| 一个|
| 3>&-| 2|一个|- ----|

  • 请注意,文件描述符2指向1,而不是3。这是因为它指向3所指向的文件描述符。因此,在下一步中关闭3时,2不会受到影响

正如您所看到的,a>&b的意思是“使 a 指向 B 当前所指向的东西”。

guz6ccqo

guz6ccqo5#

3.没有。顺序很重要,所以它去掉了原来的标准输出,然后把标准错误移到标准输出。
4. 3只是另一个文件描述符,与前3个相同。大多数进程总共可以使用256个不同的文件描述符。

相关问题