c程序中,如何使用Linux tee重定向自身的输出
In c program, how to use Linux tee to redirect the output of itself
我无法在执行 C 程序时使用 Linux 命令 tee,因为我无法在大型项目中找到准确运行该程序的代码行。我正在努力想出一种方法来调用 C 程序中的 tee 命令,以将其 printf 语句也重定向到日志文件。问题是如果没有像“./exe | tee some.log”这样的可执行文件,我就不能调用 tee,因为程序已经执行了。我做了一些关于如何获取 运行 进程的标准输出的研究,并看到一些建议检查 /proc//fd/1 的答案。但我不知道为什么“1”(stdout) 文件是空的,我期待该文件应该存储进程的 printf 输出。
衷心感谢您的帮助!
A shell 在调用程序之前使用 pipe
和 dup2
设置管道。没有理由你不能在:
之后做
void pipeto(char** cmd) {
int fds[2];
pipe(fds);
if(fork()) {
// Set up stdout as the write end of the pipe
dup2(fds[1], 1);
close(fds[0]);
close(fds[1]);
} else {
// Double fork to not be a direct child
if(fork()) exit(0);
// Set up stdin as the read end of the pipe, and run tee
dup2(fds[0], 0);
close(fds[0]);
close(fds[1]);
execvp(cmd[0], cmd);
}
}
int main() {
char* cmd[] = { "tee", "myfile.txt", NULL };
pipeto(cmd);
printf("This is a test\n");
}
结果:
$ ./foo
This is a test
$ cat myfile.txt
This is a test
请注意,由于 shell 不再知道有一个 tee
被传送到,它不会等待它。这意味着如果程序退出并且 shell 在 tee
完成写入之前重绘提示,输出可能会有点混乱。这样的输出纯粹是一个表面问题:
user@host $ ./foo
user@host $ This is a test
这并不意味着命令挂起,提示仍然有效,您可以键入命令或直接按 Enter 重绘。
我无法在执行 C 程序时使用 Linux 命令 tee,因为我无法在大型项目中找到准确运行该程序的代码行。我正在努力想出一种方法来调用 C 程序中的 tee 命令,以将其 printf 语句也重定向到日志文件。问题是如果没有像“./exe | tee some.log”这样的可执行文件,我就不能调用 tee,因为程序已经执行了。我做了一些关于如何获取 运行 进程的标准输出的研究,并看到一些建议检查 /proc//fd/1 的答案。但我不知道为什么“1”(stdout) 文件是空的,我期待该文件应该存储进程的 printf 输出。
衷心感谢您的帮助!
A shell 在调用程序之前使用 pipe
和 dup2
设置管道。没有理由你不能在:
void pipeto(char** cmd) {
int fds[2];
pipe(fds);
if(fork()) {
// Set up stdout as the write end of the pipe
dup2(fds[1], 1);
close(fds[0]);
close(fds[1]);
} else {
// Double fork to not be a direct child
if(fork()) exit(0);
// Set up stdin as the read end of the pipe, and run tee
dup2(fds[0], 0);
close(fds[0]);
close(fds[1]);
execvp(cmd[0], cmd);
}
}
int main() {
char* cmd[] = { "tee", "myfile.txt", NULL };
pipeto(cmd);
printf("This is a test\n");
}
结果:
$ ./foo
This is a test
$ cat myfile.txt
This is a test
请注意,由于 shell 不再知道有一个 tee
被传送到,它不会等待它。这意味着如果程序退出并且 shell 在 tee
完成写入之前重绘提示,输出可能会有点混乱。这样的输出纯粹是一个表面问题:
user@host $ ./foo
user@host $ This is a test
这并不意味着命令挂起,提示仍然有效,您可以键入命令或直接按 Enter 重绘。