• stdout stderr 重定向到文件


    1. stdout/stderr 重定向

    1.1. dup/dup2 重定向到已打开文件 或 新文件

    // https://www.man7.org/linux/man-pages/man2/dup.2.html
    #include 
    // 给 oldfd 分配一个新的描述符,返回
    int dup(int oldfd);
    // 给 oldfd 分配一个新的描述符 newfd,如果 newfd 已经打开,则先关闭
    // 原来只有 oldfd 一个指针,现在有2个指针执行那个句柄对应的文件啦
    int dup2(int oldfd, int newfd);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    #include 
    #include 
    
    #include 
    #include 
    #include 
    
    int mOldStdout = -1;
    int mNewStdout = -1;
    
    // stdout 输出 到文件中
    void dupOutput(char * filename)
    {
        mNewStdout = open(filename, O_CREAT|O_WRONLY|O_APPEND|O_SYNC, S_IRWXU|S_IRWXG|S_IROTH);
        mOldStdout = dup(STDOUT_FILENO);
    
        fsync(STDOUT_FILENO);
        dup2(mNewStdout, STDOUT_FILENO); // STDOUT_FILENO 指向 mNewStdout 文件,stdout 输出就会写到文件里
    }
    
    // 还原 stdout 到 命令窗口
    void restoreOutput()
    {
        fsync(STDOUT_FILENO);
    
        dup2(mOldStdout, STDOUT_FILENO);
        close(mOldStdout);
        close(mNewStdout);
    }
    
    int main(int argc, char * argv[]) {
        printf("IN STDOUT-1\n");
    
        dupOutput("logfile");
        printf("IN LOGFILE-1\n");
    
        restoreOutput();
        printf("IN STDOUT-2\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    #include 
    #include 
    
    #include 
    #include 
    #include 
    
    static FILE *logHandel = NULL;
    
    int src_stdout = -1; // 一般 stdout 的 handel 是 1. stderr 是 2
    int src_stderr = -1; // 一般 stdout 的 handel 是 1. stderr 是 2
    
    void dupOutput(int fd)
    {
        src_stdout = dup(STDOUT_FILENO);   // 保持老的 handle,用于恢复
        src_stderr = dup(STDERR_FILENO);
        fsync(STDOUT_FILENO);
        fsync(STDERR_FILENO);
        dup2(fd, STDOUT_FILENO);  // 把 STDOUT_FILENO 指向 fd 句柄
        dup2(fd, STDERR_FILENO);
    }
    
    void restoreOutput(int fd)
    {
        fsync(STDOUT_FILENO);
        fsync(STDERR_FILENO);
        dup2(src_stdout, STDOUT_FILENO);  // STDOUT_FILENO 指向原来的 handle
        dup2(src_stderr, STDERR_FILENO);
        close(src_stdout);
        close(src_stderr);
    }
    
    int log_set_path(const char *path)
    {
        if (access(path, F_OK | W_OK) == 0) {
            logHandel = fopen(path, "a+");
        }
        if (!logHandel) {
            printf("open log file(%s) error: %s\n", path, strerror(errno));
            return errno;
        }
        dupOutput(fileno(logHandel));
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    1.2. freopen 重定向到新文件

    FILE *freopen(char *filename, char *type, FILE *stream);

    freopen 类似于 fopen+dup2, 同时包含打开和重定向功能

    #include 
    int main() 
    { 
    	int a,b; 
    	freopen("D:\\in.txt","r",stdin); //输入重定向,输入数据将从D盘根目录下的in.txt文件中读取 
    	freopen("D:\\out.txt","w",stdout); //输出重定向,输出数据将保存在D盘根目录下的out.txt文件中 
    	while(scanf("%d %d",&a,&b)!=EOF) 
    	printf("%d\n",a+b); 
    	fclose(stdin);//关闭重定向输入 
    	fclose(stdout);//关闭重定向输出 
    	return 0; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    
    #include 
    #include 
    int main()
    { 
    	int a,b; 
    	freopen("D:\\in.txt","r",stdin); //输入重定向,输入数据将从D盘根目录下的in.txt文件中读取 
    	freopen("D:\\out.txt","w",stdout); //输出重定向,输出数据将保存在D盘根目录下的out.txt文件中 
    	while(cin>>a>>b) 
    	cout<
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.3. 命令行重定向

    这里主要是重定向符号的使用

    新建文件 > 追加文件 >>
    nohup java -jar app.jar >log 2>&1 &
    简写 nohup java -jar app.jar &>log &

    1.4. 参考资料

  • 相关阅读:
    Cmake升级与软链接
    CCF开源发展委员会正式成立,探索开源发展新途径
    如何理解JavaScript定时器的4种写法-附带面试题讲解
    error: subprocess-exited-with-error完美解决webitor安装不了问题
    全国心力衰竭日| 仿生“人工心脏”——心衰患者的“心”希望
    vs2022中使用gridview显示sqlserver中的数据时只显示了列而没有显示表中的数据
    企业级高负载WEB服务器—Tomcat
    自然语言处理历史史诗:NLP的范式演变与Python全实现
    java 抽象类和接口——抽象类
    机器学习——k-近邻算法、K-均值算法、PCA、异常检测算法、上限分析
  • 原文地址:https://blog.csdn.net/knowledgebao/article/details/126023783