han*_*rik 17 bash command-line pipe cmd.exe
我知道这个命令的作用:
\ncommand 1>/dev/null 2>&1\n
Run Code Online (Sandbox Code Playgroud)\n但是,如果有的话,下面的代码有什么作用呢?
\ncommand 2>&1 1>/dev/null\n
Run Code Online (Sandbox Code Playgroud)\n我仍然看到第二个命令的标准错误输出,所以它至少没有达到我预期的效果......
\n这在 Windows/cmd.exe 和 Linux/Bash 上都被重现(我本来想在Unix & Linux而不是 Super\xc2\xa0User 上问这个问题,但我注意到它也可以在 Windows cmd.exe 上重现,所以我猜它在 Super\xc2\xa0User 上比在 Unix 和 Linux 上更适合?)
\ngle*_*man 26
另一个示例可能会有所帮助:让我们将 fd1 重定向到一个文件,将 fd2 重定向到 fd1,然后将 fd1 重定向到另一个文件:
$ ( echo "this is stdout"; echo "this is stderr" >&2 ) 1>foo 2>&1 1>bar
$ cat foo
this is stderr
$ cat bar
this is stdout
Run Code Online (Sandbox Code Playgroud)
我们可以看到将2>&1
stderr 发送到 stdout 重定向到的“foo”文件,但是当我们将 stdout 重定向到“bar”时,我们不会改变 stderr 的目的地。
类似地,2>&1 1>/dev/null
将 stderr 重定向到 stdout 指向的任何内容(请参阅 参考资料/proc/$$/fd
),并且当 stdout 被丢弃时,stderr 不会改变(仍然可见)。
这是用于捕获命令错误输出的技术,忽略常规输出:
error_output=$( some_command 2>&1 1>/dev/null )
Run Code Online (Sandbox Code Playgroud)
Cyr*_*rus 12
从man bash
:
“请注意,重定向的顺序很重要。例如,命令
ls > dirlist 2>&1
Run Code Online (Sandbox Code Playgroud)
将标准输出和标准错误定向到文件目录列表,而命令
ls 2>&1 > dirlist
Run Code Online (Sandbox Code Playgroud)
仅将标准输出定向到文件 dirlist,因为在标准输出重定向到 dirlist 之前,标准错误已从标准输出复制。”
这是操作顺序的问题。您希望2>&1
重定向到1
,但它却重定向到的当前值1
。这感觉有点像“竞争条件”,但实际上并非如此,您期望两个操作同时发生,但它们是一个接一个地进行评估的,并且该特定时刻的值才是重要的,而不是最终值。
默认情况下,1
指向您的默认控制台输出stdout
,因此2>&1
此时将重定向stderr
到您的标准控制台输出stdout
。
通过在 重定向到另一个文件2>&1
后1
执行此操作,您可以将其重定向到指向的新文件指针。1
( /dev/null
)
本质上,重定向运算符复制重定向到的指针,而不是指向其他描述符。因此,重定向的顺序很重要。
1>/dev/null 2>&1
:
1 (stdout): /dev/null
2 (stderr): /dev/null
2>&1 1>/dev/null
:
1 (stdout): /dev/null
2 (stderr): 1 (stdout) 的原始目的地
顺序很重要,因为它们是从左到右处理的,使用该点描述符的当前值。
让我们看看1>/dev/null 2>&1
两种不同的起始条件:
Original After 1>/dev/null After 2>&1
----------------- ----------------- -----------------
1 (stdout): /dev/tty /dev/null /dev/null
2 (stderr): /dev/tty /dev/tty /dev/null
Run Code Online (Sandbox Code Playgroud)
Original After 1>/dev/null After 2>&1
----------------- ----------------- -----------------
1 (stdout): /tmp/stdout /dev/null /dev/null
2 (stderr): /tmp/stderr /tmp/stderr /dev/null
Run Code Online (Sandbox Code Playgroud)
现在,让我们看看2>&1 1>/dev/null
相同的起始条件。
Original After 2>&1 After 1>/dev/null
----------------- ----------------- -----------------
1 (stdout): /dev/tty /dev/tty /dev/null
2 (stderr): /dev/tty /dev/tty /dev/tty
Run Code Online (Sandbox Code Playgroud)
Original After 2>&1 After 1>/dev/null
----------------- ----------------- -----------------
1 (stdout): /tmp/stdout /tmp/stdout /dev/null
2 (stderr): /tmp/stderr /tmp/stdout /tmp/stdout
Run Code Online (Sandbox Code Playgroud)
演示
a
:
#!/usr/bin/perl
print STDOUT "Sent to STDOUT\n";
print STDERR "Sent to STDERR\n";
Run Code Online (Sandbox Code Playgroud)
$ ( exec 1>/tmp/stdout 2>/tmp/stderr; ./a )
$ cat /tmp/stdout; echo .
Sent to STDOUT
.
$ cat /tmp/stderr; echo .
Sent to STDERR
.
Run Code Online (Sandbox Code Playgroud)
$ ( exec 1>/tmp/stdout 2>/tmp/stderr; ./a 2>&1 1>/dev/null )
$ cat /tmp/stdout; echo .
Sent to STDERR
.
$ cat /tmp/stderr; echo .
.
Run Code Online (Sandbox Code Playgroud)
$ ( exec 1>/tmp/stdout 2>/tmp/stderr; ./a 1>/dev/null 2>&1 )
$ cat /tmp/stdout; echo .
.
$ cat /tmp/stderr; echo .
.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4875 次 |
最近记录: |