【问题标题】:"tee" like programming api in UNIX"tee" 类似于 UNIX 中的编程 api
【发布时间】:2011-04-12 15:34:14
【问题描述】:

我想要这样的东西

$> ps -ax | tee -a processes.txt

在 UNIX C 编程环境中,意味着不通过 shell 脚本。

基本上有一个 API 可以让我在 STDIN 和/或 STDOUT 上开球,这样我就可以自动将 CLI 上出现的任何内容记录到文件中。想象一下,有一个前台进程与用户交互并响应一些输出到终端。我希望将终端中显示的所有内容也保存在一个文件中以供以后检查。

我想像这样神奇的东西:

tee(STDIN, "append", logFile);

谢谢!

跟进,这是我根据 Lars 编写的程序(请参阅下面的答案部分),但不完全是我想要的:

int main(int argc, char** argv){

        int pfd[2];
        if (pipe(pfd) == -1) { perror("pipe"); }


        if (fork()==0) { // child reads from pipe
                close(pfd[1]);

                mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
                int ufd = open("user_study.log", O_CREAT | O_APPEND | O_WRONLY, mode);
                if (ufd == -1) {
                        perror("Cannot open output file"); exit(1);
                } // ++

                char buf;
                while (read(pfd[0], &buf, 1) > 0) {
                        write(STDOUT_FILENO, &buf, 1); // write to stdout
                        write(ufd, &buf,1);            //   and to log
                }

                close(pfd[0]);

        } else { // parent write to pipe
                // dup STDOUT to the pipe
                close(pfd[0]);
                dup2(pfd[1], STDOUT_FILENO);

                char msg[200];
                msg[0] = "";
                do {
                        scanf("%s", msg);
                        printf("program response..");

                } while (strcmp(msg, "exit")!=0);

                close(pfd[1]);

        }

        return 1;
}

实际运行:

[feih@machine ~/mytest]$ ./a.out
abc
haha
exit 
program response..   <---- the output is delayed by the chld process, not desired
program response..
program response..

[feih@machine ~/mytest]$ less user_study.log
program response..   <---- the log doesn't contain input
program response..
program response..

期望的运行和日志(模拟):

[feih@machine ~/mytest]$ ./a.out
abc
program response..
haha
program response..
exit 
program response..


[feih@machine ~/mytest]$ less user_study.log 
abc
program response..      <--- the log should be the same as the running
haha
program response..
exit 
program response..

所以到目前为止,这个问题还没有完全解决。

【问题讨论】:

  • 所以你的意思是你希望每个printf(等)都将数据写入stdout和文件?
  • 结果和你说的一样。但是我不想在printf 这边做,而是在stdout 那边做。有点像一次性设置,因为printf 可以无处不在。
  • 你不能用一个辅助函数来代替printf吗?并且有那个辅助函数调用printffprintf
  • 如果您希望 log/stdout 包含输入,您需要明确地回显它。您还需要将父级的标准输出缓冲设置为无(参见 setbuf)。
  • 听起来你想实现类似script的东西。

标签: c unix io


【解决方案1】:

你可以这样做:

  • 创建管道(参见pipe(2)
  • 分叉
  • 在子级中,从管道读取并写入每个输出
    • stdout 和一个文件,或者任何你需要的东西
  • 在父级中,将标准输出重定向到管道(参见dup2(2)

您需要处理很多棘手的问题,但这是可行的。

如果没有额外的进程,你就无法做到这一点,因为 printf 只写入一个文件描述符(stdout 那个)。

【讨论】:

  • 你可以用第二个线程而不是分叉做类似的事情,但你必须先复制标准输出然后关闭它并用管道的写入端替换它。
  • Lars,我尝试了你的建议,但这并不是我想要的:
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 2013-07-01
相关资源
最近更新 更多