Linux output redirection ">", ">>", "freopen"

Sometimes, we use printf or fprintf to print out debugging information or error messages when coding, but normally, printing in this way will only be displayed on the terminal. If the terminal is closed, or the system is down, etc., these output information will be gone. , in order to save these important information, the output can be redirected to a file, and the information can be directly output to the file and saved.


The essence of Linux is that everything is a file, and input and output devices also exist and are managed in the form of files.

For any program running in Linux, the Linux system will create 3 open streams for it, which are used for input (0: stdin), output (1: stdout), and printing diagnostic and error information (2: stderr). Usually they will be connected to user terminals. The type of these three handles is a pointer to FILE. It can be used by functions such as fprintf, fread, etc. After the program starts, the file descriptors of stdin, stdout, and stderr are 0, 1, and 2, and other file descriptors are arranged after that.

Note: stderr is not cached, but stdout is cached.

It means: with caching function, the output will not be printed until the carriage return '\n' is encountered, otherwise it will remain in the buffer; while without any caching function, there is no limit, and the output will be printed directly. example:

#include <unistd.h>
#include <stdio.h>


int main(int argc, char **argv) {
    
    for (int i = 0; i < 5; i++) {
        //fprintf(stdout, "This is stdout[%d]\n", i);
		fprintf(stdout, "This is stdout[%d]", i);
        sleep(1);
    }

    fprintf(stdout, "\n");

    for (int i = 0; i < 5; i++) {
        fprintf(stderr, "This is stderr[%d]", i);
        sleep(1);
    }

    fprintf(stderr, "\n");
    sleep(5);

    return 0;
}

 It can be seen that the statements output in the first for loop are output together, and it is output together after encountering fprintf(stdout, "\n"); this line of code outputs the carriage return. From this, it can be proved that stdout is really cached and will be output until a carriage return is encountered. stderr is not affected and output normally.

 If you need to make stdout output normally, just add "\n"! Code as commented above!

Thinking: Many times we use printf to print information to debug the program, but if the terminal is closed, how to display the printf debugging information?


redirect

1. >

        When running the program, add "> file name" to output the string of standard output (stdout) in the code to the specified file. It is worth noting that standard error (stderr) cannot be output to a file in this way. example:

        

#include <unistd.h>
#include <stdio.h>


int main(int argc, char **argv) {
    
    printf("输出重定向:printf...\n");
    fprintf(stdout, "输出重定向:fprintf(stdout)...\n");
    fprintf(stderr, "输出重定向:fprintf(stderr)...\n");
    perror("输出重定向:perror...\n");

    return 0;
}

normal operation:   

(The last output ":Success" is output by perror, because the errno global variable does not store the error flag, so it outputs Success)

Output redirected to file:

 It can be seen that the standard output has been output to the file.

So how should the standard error be output to a file? Continue to enter " 2>&1 " at the end of the operation .

For example: ./redirector > test.log 2>&1 

 All output to the file; however, it outputs standard error first, and then standard output, why? I think it should be caused by the cache!

In addition, using ">" to redirect to a file will overwrite the previous information, so how to append it?

2. >>

        Use ">>" to achieve additional effects. ./redirector >> test.log 2>&1   

3. freopen        

FILE *freopen(const char *path, const char *mode, FILE *stream);

path : file name

mode

            mode                                         describe
                r Open the file for reading, the file must exist.
                r+ Open the file for reading and writing. The file must exist.
                w Open the file in write mode, create it if it does not exist, and overwrite it if it exists.
                w+ Open the file in read-write mode, create it if it does not exist, and overwrite it if it exists.
                a Open the file in the append mode, append at the end, and create the file if it does not exist.
                a+ Append mode opens the file, appends to the end, and can be read.

stream : the value stdout or stderr.

example:

#include <unistd.h>
#include <stdio.h>


int main(int argc, char **argv) {
    
    FILE *out = freopen("test1.log", "a", stdout);
    //FILE *out = freopen("test1.log", "a", stderr);
    
    printf("输出重定向:printf...\n");
    fprintf(stdout, "输出重定向:fprintf(stdout)...\n");
    fprintf(stderr, "输出重定向:fprintf(stderr)...\n");
    perror("输出重定向:perror...\n");

    fclose(stdout);
    //fclose(stderr);

    return 0;
}

 Using the file opened by stdout will only write the flag output to the file; using stderr will write the flag error to the file!

Of course, we must understand that printf outputs to a file, which will cause IO interruption, so the efficiency of executing printf is much lower than that of ordinary instructions.


Summarize:

        Normally, when we debug code or some small example codes, redirection can be used; but for large projects, it is recommended to use engineering-level logs, such as log4 or plog.

Guess you like

Origin blog.csdn.net/cpp_learner/article/details/128642939