【问题标题】:Reading value of `stdout` and `stderr`读取`stdout`和`stderr`的值
【发布时间】:2017-05-13 04:24:53
【问题描述】:

我正在尝试使用以下命令读取 stdoutstderr 的值:

cat /dev/stderr

cat /dev/stdout 

但是,命令继续运行。

【问题讨论】:

  • 它是由某些命令生成的吗?或者你想在这里阅读谁的stdoutstderr
  • /dev/stderr/dev/stderr像文件是真的吗?
  • kindof,您可能需要阅读en.wikipedia.org/wiki/Standard_streams
  • stdout 的“rhe 值”是什么意思?你期望什么样的输出?
  • 当您键入命令时,例如echo "hello world",该命令的结果hello world 会显示在标准输出中。

标签: linux bash shell sh


【解决方案1】:

改用 FIFO

从技术上讲,/dev/stdout/dev/stderr 是真正的文件描述符,而不是 FIFO 或命名管道。在我的系统上,它们实际上只是 /dev/fd/1/dev/fd/2 的符号链接。这些描述符通常与您的 TTY 或 PTY 相关联。因此,您无法真正按照您尝试的方式阅读它们。

您可能想要的是 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

作为一个更详细但不那么扭曲的例子,考虑一下:

$ ruby -e 'STDERR.puts "Some error."' 2> error & cat error
[1] 32458
Some error.
[1]+  Done                    ruby -e 'STDERR.puts "Some error."' 2> error

在此示例中,Ruby 使用标准错误将字符串写入我们之前创建的 error FIFO。写入发生在后台,但会阻塞,直到 cat 命令清空 FIFO。一旦 FIFO 被清空,后台作业就完成了。

FIFO 只是一种特殊类型的文件,因此您可以在使用完rm error 后将其删除。

【讨论】:

  • 我认为( echo foo >&2 2> error & ) 的重定向顺序错误。这会将标准输出重定向到任何标准错误(终端),然后将标准错误重定向到管道。由于没有读卡器,打开管道时进程仍然阻塞,但cat 没有从管道中得到任何东西,只是启动它释放echo 以写入终端。试试... | cat >/dev/null... | cat -n
【解决方案2】:

我真的不知道你读取stderrstdin 的值是什么意思,但我可以告诉你为什么cat /dev/stderr 会继续运行:它正在等待从fd 读取数据。

在我可以测试的系统上,两个输出 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

行首的权限位表示fd的0到2都开放读写。

从他们那里阅读也可以在实践中使用(斜体输入):

$ cat /dev/stderr 富 富 $ 读取 -u 2 ;回声“回复:$回复” asdf 回复:asdf

虽然真的,如果我们想在终端上进行交互,即使有重定向,最好只打开/dev/tty 并从那里读取。 (例如,ssh 就是这样询问密码的。)

【讨论】:

    猜你喜欢
    • 2020-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    相关资源
    最近更新 更多