我怎样才能实现“tee”?用C语言编程?
我正在寻找一种用 C 语言以编程方式(即不使用命令行重定向)实现“tee”功能的方法,以便我的标准输出同时转到标准输出和日志文件。这需要适用于我的代码和输出到标准输出的所有链接库。有办法做到这一点吗?
I'm looking for a way in C to programmatically (ie, not using redirection from the command line) implement 'tee' functionality such that my stdout goes to both stdout and a log file. This needs to work for both my code and all linked libraries that output to stdout. Any way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以
popen()
tee 程序。或者您可以通过像这样的子进程
fork()
和管道stdout
(改编自我编写的真实程序,所以它有效!):You could
popen()
the tee program.Or you can
fork()
and pipestdout
through a child process such as this (adapted from a real live program I wrote, so it works!):“
popen()
tee”的答案是正确的。下面是一个完全执行此操作的示例程序:说明:
popen()
返回一个FILE*
,但dup2()
需要一个文件描述符 ( fd),因此fileno()
将FILE*
转换为 fd。然后 dup2(..., STDOUT_FILENO) 表示将 stdout 替换为 popen() 中的 fd。这意味着,您生成一个子进程 (
popen
),将其所有输入复制到 stdout 和一个文件,然后将 stdout 移植到该进程。The "
popen()
tee" answers were correct. Here is an example program that does exactly that:Explanation:
popen()
returns aFILE*
, butdup2()
expects a file descriptor (fd), sofileno()
converts theFILE*
to an fd. Thendup2(..., STDOUT_FILENO)
says to replace stdout with the fd frompopen()
.Meaning, you spawn a child process (
popen
) that copies all its input to stdout and a file, then you port your stdout to that process.您可以使用
pipe(2)
和dup2(2)
将标准输出连接到您可以读取的文件描述符。然后,您可以有一个单独的线程监视该文件描述符,将其获取的所有内容写入日志文件和原始标准输出(在连接管道之前通过 dup2 保存到另一个文件描述符)。但你需要一个后台线程。实际上,我认为 vatine 建议的 popen tee 方法可能更简单、更安全(只要您不需要对日志文件执行任何额外操作,例如时间戳或编码等)。
You could use
pipe(2)
anddup2(2)
to connect your standard out to a file descriptor you can read from. Then you can have a separate thread monitoring that file descriptor, writing everything it gets to a log file and the original stdout (saved avay to another filedescriptor bydup2
before connecting the pipe). But you would need a background thread.Actually, I think the popen tee method suggested by vatine is probably simpler and safer (as long as you don't need to do anyhing extra with the log file, such as timestamping or encoding or something).
您可以将
forkpty()
与exec()
结合使用,通过其参数来执行受监控的程序。forkpty()
返回一个文件描述符,该描述符被重定向到程序 stdin 和 stdout。写入文件描述符的任何内容都是程序的输入。程序写入的任何内容都可以从文件描述符中读取。第二部分是循环读取程序的输出并将其写入文件并将其打印到标准输出。
例子:
You can use
forkpty()
withexec()
to execute the monitored program with its parameters.forkpty()
returns a file descriptor which is redirected to the programs stdin and stdout. Whatever is written to the file descriptor is the input of the program. Whatever is written by the program can be read from the file descriptor.The second part is to read in a loop the program's output and write it to a file and also print it to stdout.
Example:
在 C 中没有简单的方法可以做到这一点。我怀疑最简单的方法是调用 popen(3),以 tee 作为命令,以所需的日志文件作为参数,然后 dup2(2) 新打开的文件描述符FILE* 到 fd 1 上。
但这看起来有点难看,我必须说我还没有尝试过这个。
There's no trivial way of doing this in C. I suspect the easiest would be to call popen(3), with tee as the command and the desired log file as an arument, then dup2(2) the file descriptor of the newly-opened FILE* onto fd 1.
But that looks kinda ugly and I must say that I have NOT tried this.