Redirecionamento de saída do Linux ">", ">>", "freopen"

Às vezes, usamos printf ou fprintf para imprimir informações de depuração ou mensagens de erro ao codificar, mas normalmente, a impressão dessa maneira só será exibida no terminal. Se o terminal estiver fechado ou o sistema estiver inativo, etc., essas saídas as informações desaparecerão. , para salvar essas informações importantes, a saída pode ser redirecionada para um arquivo e as informações podem ser enviadas diretamente para o arquivo e salvas.


A essência do Linux é que tudo é um arquivo, e os dispositivos de entrada e saída também existem e são gerenciados na forma de arquivos.

Para qualquer programa em execução no Linux, o sistema Linux criará 3 fluxos abertos para ele, que são usados ​​para entrada (0: stdin), saída (1: stdout) e impressão de informações de diagnóstico e erro (2: stderr). Normalmente eles serão conectados aos terminais do usuário. O tipo dessas três alças é um ponteiro para FILE. Ele pode ser usado por funções como fprintf, fread, etc. Após o início do programa, os descritores de arquivo stdin, stdout e stderr são 0, 1 e 2, e outros descritores de arquivo são organizados depois disso.

Nota: stderr não é armazenado em cache, mas stdout é armazenado em cache.

Isso significa: com a função de cache, a saída não será impressa até que o retorno de carro '\n' seja encontrado, caso contrário, permanecerá no buffer; enquanto sem qualquer função de cache, não há limite e a saída será impressa diretamente . exemplo:

#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;
}

 Pode-se ver que as instruções produzidas no primeiro loop for são exibidas juntas e são exibidas juntas após encontrar fprintf(stdout, "\n"); esta linha de código gera o retorno de carro. A partir disso, pode-se provar que stdout é realmente armazenado em cache e será exibido até que um retorno de carro seja encontrado. stderr não é afetado e sai normalmente.

 Se você precisar fazer a saída stdout normalmente, basta adicionar "\n"! Código conforme comentado acima!

Pensando: Muitas vezes usamos printf para imprimir informações para depurar o programa, mas se o terminal estiver fechado, como exibir as informações de depuração do printf?


redirecionar

1. >

        Ao executar o programa, adicione "> nome do arquivo" para gerar a string de saída padrão (stdout) no código para o arquivo especificado. Vale a pena notar que o erro padrão (stderr) não pode ser enviado para um arquivo dessa maneira. exemplo:

        

#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;
}

operação normal:   

(A última saída ":Success" é gerada por perror, porque a variável global errno não armazena o sinalizador de erro, então ela gera Success)

Saída redirecionada para o arquivo:

 Pode-se ver que a saída padrão foi enviada para o arquivo.

Então, como o erro padrão deve ser enviado para um arquivo? Continue a inserir " 2>&1 " no final da operação .

Por exemplo: ./redirector > test.log 2>&1 

 Todas as saídas para o arquivo; no entanto, ele gera primeiro o erro padrão e, em seguida, a saída padrão, por quê? Acho que deve ser causado pelo cache!

Além disso, usar ">" para redirecionar para um arquivo sobrescreverá as informações anteriores, então como anexá-las?

2. >>

        Use ">>" para obter efeitos adicionais. ./redirector >> test.log 2>&1   

3. Freopen        

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

caminho : nome do arquivo

modo :

            modo                                         descrever
                r Abra o arquivo para leitura, o arquivo deve existir.
                r+ Abra o arquivo para leitura e gravação. O arquivo deve existir.
                c Abra o arquivo no modo de gravação, crie-o se não existir e substitua-o se existir.
                w+ Abra o arquivo no modo de leitura/gravação, crie-o se não existir e sobrescreva-o se existir.
                a Abra o arquivo no modo de acréscimo, anexe no final e crie o arquivo se ele não existir.
                a+ O modo Anexar abre o arquivo, anexa ao final e pode ser lido.

stream : o valor stdout ou stderr.

exemplo:

#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;
}

 Usar o arquivo aberto por stdout apenas gravará a saída do sinalizador no arquivo; usar stderr gravará o erro do sinalizador no arquivo!

Obviamente, devemos entender que printf gera um arquivo, o que causará interrupção de E/S; portanto, a eficiência da execução de printf é muito menor do que a das instruções comuns.


Resumir:

        Normalmente, quando depuramos um código ou alguns pequenos códigos de exemplo, o redirecionamento pode ser usado; mas para grandes projetos, é recomendável usar logs de nível de engenharia, como log4 ou plog.

Acho que você gosta

Origin blog.csdn.net/cpp_learner/article/details/128642939
Recomendado
Clasificación