文件描述符2打开用于读写

文件描述符2打开用于读写

这是我从我写的 stderr 读取的 C 程序

#include <uninstd.h>
#include <stdio.h>

int main(void) {
 char buff[3];
 read(2, buff, sizeof(buff));
 printf("%s", buff");
 return 0;
}

我的问题是如何向它发送 stderr。大多数搜索显示为 bash 重定向

command 2> file

但这会将 stderr 发送到文件。

我怎样才能传递到我的程序。就像点一样,

command 2 "somthing here" ./myprogram

感谢您的回答。

答案1

鉴于大多数参考书和文档总是将标准错误作为输出,这让许多人感到惊讶,事实上它通常是已经打开读+写。非常喜欢你的节目从文件描述符 2 读取。

(注意:在这个答案中,我使用实际的文件描述符编号。C流例如stderr不需要实际对应这些文件描述符,因为程序可以更改它们,并且它增加了谈论 C 流的作用的一层混乱。您的程序正在使用read()。)

文件描述符2打开用于读写

对于在父进程中未使用重定向的登录会话中的程序,文件描述符 2(标准错误)通常是文件描述符 0(标准输入)的副本。它们都引用相同的底层文件描述,它通常是登录会话的终端(由ttymon或在旧系统上getty在会话开始时打开和复制)。

如果从文件描述符 2 读取,您将获得与从文件描述符 0 读取相同的输入。

顺便说一句:从文件描述符 2 中读取数据经常用于密码输入等操作;在该/dev/tty设备推出之前,大约在 1977 年。从文件描述符 2 读取的原因是当文件描述符 0 已重定向到其他地方时(例如,在管道中间的情况),从原始终端获取输入。

尽管/dev/ttyPOSIX 已经存在很长时间了,超过 40 年了,但它仍然要求文件描述符 2 也打开以供读取。

你的程序没有做什么

从文件描述符 2 读取另一个程序的输出是另一回事。你不能轻易做到这一点通过它自己,不将标准输出与标准错误合并。它通常涉及一系列3>&1 1>&2 2>&3或类似的交换。一些 shell 通过调用允许在输出文件描述符 2 上使用管道

prog1 2| prog2

但这样的贝壳很少见,这并不是什么你的无论如何,程序都需要。

将输入发送到您的程序

如果您希望您的程序从文件描述符 2 读取内容,则可以读取某些内容其他与从终端相比,您当然可以重定向该文件描述符。你可以使用正常的输入重定向语法(<shell 中的运算符),但程序中的库,甚至您在其他地方编写的其他代码,都会假设它们可以写入此文件描述符。

shell 允许您使用<>重定向运算符来显式打开文件以进行读取和写入。这是您在重定向程序的文件描述符 2 时使用的。

./myprogram 2<>filename

除了 shell 重定向之外,还有很多工具可以操作文件描述符。例如:Laurent Bercot 的链式加载redirfd工具,与 execline 一起提供,这个重定向看起来更像你的假设:

redirfd -u 2 filename ./myprogram

Bourne Again 和 Z shell(但不是 Almquist shell)等 shell 语法也为文件描述符 2 提供“此处文档”和“此处字符串”。请注意,文件描述符 2 已打开只读在这种情况下通过这些外壳。

./myprogram 2<<< "here string"

答案2

stderr是为了写作,而不是阅读。有时它是一个dup重复stdin(例如,当所有 3 个输入/输出/错误都连接到终端时)。要读取另一个程序的 stderr,您可以将该程序的 stderr 重定向到另一个程序的 stdin。

例如 指向stdout一个文件,然后stderr指向./myprograms's stdin

command 2>&1 >a_file | ./myprogram

答案3

bash使用像and 之类的 shell zsh(但不是普通的 POSIX sh),您可以通过 将一个程序的标准错误重定向到另一个程序的标准输入firstprogram 2> >(second program)

例子:

$ perl -E 'say "perl stdout"; warn "perl stderr\n"' 2> >(awk '{print "awk", $0}')
perl stdout
awk perl stderr

答案4

要让 shell 设置输入重定向stderr,您可以使用<,<<<<<并在文件描述符编号前加上前缀:

./myprog 2< somefile.txt

或者

./myprog 2<<< "some text"

但如果你stderr像那样重定向,程序就不能输出到它,这意味着您不会看到程序(或其使用的任何库)可能尝试打印的任何错误消息,此外,程序还会因尝试写入这些消息而出现错误。

您可能需要重新考虑是否有其他方法可以完成您正在做的事情。至少,如果想法是为程序提供一些输入,请考虑使用例如 fd 3。

相关内容