我想把 stdout
分成两份,一份输出到 stdout
,另一份输出到 stderr
。听起来像是使用 tee
的工作,但是语法让我很困惑 -
./script.sh | tee stderr
当然,这里应该如何引用stderr
?我找到的唯一支持交互和非交互shell的跨平台方法是:
command | tee >(cat 1>&2)
tee的参数是文件或文件句柄。使用过程替代,我们将输出发送到进程中。在=cat=进程中,我们将标准输出重定向到标准错误输出。Shell(bash / ksh)负责设置1和2文件描述符。
#!/bin/bash
。因为 sh
不支持 >( xxxx )
。 - Sungam/dev/fd/2
或 /proc/self/fd/2
不一定存在并且具有写入权限。 - yurenchen./script.sh | tee /dev/fd/2
请注意,这取决于操作系统的支持,而不是tee内置的任何功能,因此并非普遍适用(但在MacOS、Linux、Solaris、FreeBSD上可以使用,可能还有其他系统)。
open()
获取输出fd)。 - Nicholas Wilsonbash
的 manpage 暗示它接受 /dev/fd/2
作为文件描述符 2 的文件名,即使文件系统没有这样的文件。 - chepnerbash
解释,因此在这里并不起作用。 - Nicholas Wilson/dev/fd/2
的内容,可能会导致翻译失败。例如,如果使用root
用户登录,则您的终端将归属于root
用户。因此,如果您切换到其他用户,则将无权访问/dev/fd/2
。 - Michał Górny/proc/self/fd/2
可能也是可用的。实际上,在我的系统 [CentOS6] 中,/dev/fd
是一个指向 /proc/self/fd
的符号链接。 - Sammitch/dev/stderr
权限用户并不总是拥有写入权限:
例如,在使用sudo之后:
sudo su - nobody -s /bin/bash
nobody@test:/$ ls -lh /dev/stderr /dev/fd/2 /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun 10 2021 /dev/stderr -> /proc/self/fd/2
lrwx------ 1 nobody nogroup 64 Apr 7 01:58 /dev/fd/2 -> /dev/pts/5
lrwx------ 1 nobody nogroup 64 Apr 7 01:58 /proc/self/fd/2 -> /dev/pts/5
nobody@test:/$ echo hell >&2
hell
nobody@test:/$ echo hell >/dev/fd/2
-su: /dev/fd/2: Permission denied
nobody@test:/$ echo hell >/dev/stderr
-su: /dev/stderr: Permission denied
nobody@test:/$ echo hell > /dev/pts/5
-su: /dev/pts/5: Permission denied
awk
nobody@test:/$ echo hell | awk '{print>"/dev/stderr";print}'
hell
hell
nobody@test:/$ echo ' hell 12 ' | awk '{print|"cat 1>&2";print}'
hell 12
hell 12
虽然有>"/dev/stderr"
,但它与shell中的不完全相同。
也许awk
不如tee
高效,
但值得注意的是,真正的stderr
。
找出差异
待续...
./script.sh 2>&1 >/dev/null | tee stderr.out
这会将 STDERR 打开到 STDOUT,然后处理掉 STDOUT。
/dev/null
。 - Lexi
/dev/stderr
。我没有遇到过没有/dev/std{in, out,err}
的系统,但这并不意味着它们不存在。Mac OS X 10.7.5和Solaris都有这两个;Linux也有这两个。 AIX 6没有这些,HP-UX 11.00也没有这些。 - Jonathan Lefflerbash
接受/dev/stderr
作为标准错误的同义词,无论文件系统中是否存在该文件;这是一个特殊情况。 - chepner/dev/fd/2
和/dev/stderr
; bash手册中有关重定向的说明:当文件名用于重定向时,Bash会特殊处理几个文件名,... - Joel Purra