bash `stdout` 和 `stderr` 的读取值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43949166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reading value of `stdout` and `stderr`
提问by stack4rme
I am trying to read value of stdout
and stderr
using the following commands:
我正在尝试读取stdout
并stderr
使用以下命令的值:
cat /dev/stderr
cat /dev/stdout
But, the command keeps running.
但是,该命令一直在运行。
回答by Todd A. Jacobs
Use a FIFO Instead
改为使用 FIFO
Technically, /dev/stdoutand /dev/stderrare really file descriptors, not FIFOs or named pipes. On my system, they're actually just symlinks to /dev/fd/1and /dev/fd/2. Those descriptors are typically linked to your TTY or PTY. So, you can't really read from them the way you're trying to do.
从技术上讲,/dev/stdout和/dev/stderr实际上是文件描述符,而不是 FIFO 或命名管道。在我的系统上,它们实际上只是指向/dev/fd/1和/dev/fd/2 的符号链接。这些描述符通常链接到您的 TTY 或 PTY。因此,您无法真正按照自己的方式阅读它们。
What you probably want is the mkfifoutility. For example, to write to standard error, and then read it from another command or script:
您可能想要的是mkfifo实用程序。例如,写入标准错误,然后从另一个命令或脚本中读取它:
# Create a named pipe.
$ mkfifo error
# See what a named pipe looks like in the filesystem.
$ ls -l error
prw-r--r-- 1 user staff 0 May 13 01:47 error|
# In a subshell: echo to stdout, duplicate stdout to stderr,
# write stderr to the error FIFO. Background to avoid blocking.
# Then read from the FIFO until empty, which ends both tasks.
$ ( echo foo >&2 2> error & ); cat error
foo
As a more verbose but less contorted example, consider this:
作为一个更冗长但不那么扭曲的例子,考虑一下:
$ ruby -e 'STDERR.puts "Some error."' 2> error & cat error
[1] 32458
Some error.
[1]+ Done ruby -e 'STDERR.puts "Some error."' 2> error
In this example, Ruby uses standard error to write a string to the errorFIFO we created earlier. The write happens in the background, but blocks until the FIFO is emptied by the catcommand. Once the FIFO is emptied, the background job completes.
在此示例中,Ruby 使用标准错误将字符串写入我们之前创建的错误FIFO。写入发生在后台,但会阻塞直到 FIFO 被cat命令清空。一旦 FIFO 被清空,后台作业就完成了。
The FIFO is just a special type of file, so you can remove it when you're done with rm error
.
FIFO 只是一种特殊类型的文件,因此您可以在使用完rm error
.
回答by ilkkachu
I don't really know what you mean by reading the value of stderr
or stdin
, but I can tell you why that cat /dev/stderr
would keep running: it's waiting for data to read from the fd.
我真的不知道读取stderr
or的值是什么意思stdin
,但我可以告诉你为什么它cat /dev/stderr
会继续运行:它正在等待从 fd 读取数据。
On the systems I can test this on, both output fd's are connected to the terminal just like stdin
is, and reading from them works just fine. On Linux, we can view this with:
在我可以测试的系统上,两个输出 fd 都像stdin
现在一样连接到终端,并且从它们读取工作得很好。在 Linux 上,我们可以通过以下方式查看:
$ ls -l /proc/self/fd
lrwx------ 1 nobody nogroup 64 May 13 21:47 0 -> /dev/pts/1
lrwx------ 1 nobody nogroup 64 May 13 21:47 1 -> /dev/pts/1
lrwx------ 1 nobody nogroup 64 May 13 21:47 2 -> /dev/pts/1
lr-x------ 1 nobody nogroup 64 May 13 21:47 3 -> /proc/44664/fd
The permission bits at the start of the line show that all of the fd's 0 to 2 are opened for both reading and writing.
该行开头的权限位显示所有 fd 的 0 到 2 都为读取和写入打开了。
Reading from them works in practice, too (input in italics):
阅读它们在实践中也有效(斜体输入):
$ cat /dev/stderr foo foo $ read -u 2 ; echo "reply: $REPLY" asdf reply: asdf
Though really, it might be better to just open /dev/tty
and read from there if we want to interact on the terminal even when there are redirections in place. (That's what ssh
does to ask the password, for example.)
虽然实际上,/dev/tty
如果我们想在终端上进行交互,即使有重定向,最好从那里打开并阅读。(例如,这就是ssh
询问密码的作用。)