读取`stdout`和`stderr`的值

时间:2017-05-13 04:24:53

标签: linux bash shell sh

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

cat /dev/stderr

cat /dev/stdout 

但是,命令一直在运行。

2 个答案:

答案 0 :(得分:2)

使用FIFO代替

从技术上讲, / dev / stdout / dev / stderr 实际上是文件描述符,而不是FIFO或命名管道。在我的系统上,他们实际上只是#em> / 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使用标准错误将字符串写入我们之前创建的错误 FIFO。写入在后台发生,但阻塞直到FIFO被 cat 命令清空。清空FIFO后,后台作业完成。

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

答案 1 :(得分:0)

通过阅读Ticket ticketBody = new Ticket { ClientName = clientName, ClientLocation = clientLocation, TicketSource = ticketSource, TicketType = ticketType, Title = title, Priority = priority, Status = status, Details = details, OpenDate = Convert.ToString(openDate.ToString("MM/dd/yyyy HH:mm:ss")), Queue = queue }; List<Ticket> bodyList = new List<Ticket>(); bodyList.Add(ticketBody); stderr的值,我真的不知道你的意思,但我可以告诉你stdin为什么会继续运行:它正在等待数据到从fd读到。

在我可以测试它的系统上,两个输出fd都像cat /dev/stderr一样连接到终端,并且从它们读取工作正常。在Linux上,我们可以通过以下方式查看:

stdin

该行开头的权限位显示所有fd的0到2都被打开以进行读写。

从他们那里读书也在实践中工作(用斜体输入):

$ cat /dev/stderr
foo
foo
$ read -u 2 ; echo "reply: $REPLY"
asdf
reply: asdf

尽管如此,如果我们想在终端上进行交互,即使有重定向,也可以更好地打开$ 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 并从那里读取。 (例如,这就是/dev/tty要求输入密码的方式。)