REdirecionar stdout ! [RESOLVIDO]

1. REdirecionar stdout ! [RESOLVIDO]

???
gokernel

(usa Linux Mint)

Enviado em 25/11/2018 - 10:37h


Olá pessoal !



Tenho esse código:

//-------------------------------------------------------------------
//
// ARQUIVO:
//   redirect.c
//
// COMPILE:
//   redirect.c -o redirect -Wall
//
//-------------------------------------------------------------------
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <io.h>
#include <fcntl.h>
//#include <windows.h>

#define STRING_LEN 50000

char string [STRING_LEN+1];
int out_pipe[2];
int saved_stdout;


int main (void) {

    saved_stdout = dup (STDOUT_FILENO); // salva stdout para no final restaurar

    #ifdef WIN32
    if (_pipe (out_pipe, sizeof(string), O_BINARY) != 0 ) {
    #endif
    #ifdef __linux__
    if (pipe(out_pipe) != 0 ) {
    #endif
        exit(1);
    }

    dup2 (out_pipe[1], STDOUT_FILENO); // REdireciona stdout para o pipe
    close (out_pipe[1]);

    // so para testar ...
//    system ("gcc -v"); //-------------------  LINHA 42  ---------------------
    system ("hello"); // meu programa teste

    printf ("HELLO WORLD\n");
    fflush (stdout);

    read (out_pipe[0], string, STRING_LEN); // ler o pipe ... "string"

    dup2 (saved_stdout, STDOUT_FILENO); // restaura stdout para teste
    printf("MY_STRING(\n%s)\n", string);

    return 0;
}
 


Usando a linha 42 NAO FUNCIONA: system ("gcc -v");
Usando a linha 43 funciona: system ("hello");


PERGUNTAS:
01 - O quem tem o GCC que não consegue REdirecionar para o string ? ... LINHA 42 do código.
02 - Alguém sabe como fazer para executar o GCC ( lLINHA 42 ) e a saida ser REdirecionada para o string ?

INFO: Executando "o meu programa hello" | system ("hello"); // meu programa teste ... LINHA 43
A saida sai correta assim:

MY_STRING(
Hello World -- My program
HELLO WORLD
)


Meu Programa:

#include <stdio.h>

int main (void) {
    printf ("Hello World -- My program\n");
    return 0;
}
 


Fui claro ?

Grato !



  


2. Re: REdirecionar stdout !

???
gokernel

(usa Linux Mint)

Enviado em 25/11/2018 - 11:01h

Só mais uma info !

E nem usando ( popen ) funciona... para REdirecionar para o "string":

    if ((fp = popen ("gcc -v", "r")) != NULL) {
       pclose(fp);
    }
 




3. Re: REdirecionar stdout !

Paulo
paulo1205

(usa Ubuntu)

Enviado em 25/11/2018 - 12:09h

Seria melhor se em lugar de dizer simplesmente que não funciona, você dissesse também o que realmente acontece.

A forma mais canônica de se fazer o que você quer no mundo UNIX (e que grosseiramente se assemelha ao que acontece quando você chama popen() com modo "r") é a seguinte.
int pipe_fds[2];
if(pipe(pipe_fds)==-1){
  perror("pipe");
  exit(1);
}
pid_t child=fork();
if(child==-1){
  perror("fork");
  exit(1);
}
if(child==0){
  /* Processo filho que envia dados para o pai; logo fechar o descritor de leitura do pipe. */
  /* Se ele tiver de ler do pai, você deve inverter os descritores e usar STDIN_FILENO. */
  /* Se a comunicação foi bidirecional, serão necessários dois pipes! */
  close(pipe_fds[0]);
  if(dup2(pipe_fds[1], STDOUT_FILENO)==-1){
    perror("dup2 in child");
    _exit(1);
  }
  close(pipe_fds[1]);
  execlp("gcc", "gcc", "-v", NULL);
  perror("execlp in child");
  _exit(1);
}
/* Processo pai. */
/* Fecha o descritor de escrita, para que só o filho escreva nele. */
/* Se o filho tiver de ler dados enviados pelo pai, inverta os descritores. */
close(pipe_fds[1]);
while(has_data(pipe_fds[0])){
  read_and_use_data(pipe_fds[0]);
}
close(pipe_fds[0]);
int child_status;
waitpid(child, &child_status, 0); 


Com popen(), seria desta maneira.
FILE *from_child=popen("gcc -v", "r");  // Cuida internamente de fazer pipe(), dup2() e close()s apropriados.
if(!from_child){
  perror("popen");
  exit(1);
}
while(!feof(from_child)){
  read_and_use_data(from_child);
}
fclose(from_child);  // Cuida de fazer o waitpid() internamente, mas não entrega o status de saída. 


Quando você usa system(), você tem o equivalente das partes de fork() e waitpid() no primeiro código acima, mas não tem o tratamento dos pipes (incluindo os dup2() e close() apropriados). Como você não foi específico sobre o erro que encontrou, eu não sei dizer se a causa é a falta desse tratamento ou se alguma outra coisa.


4. Re: REdirecionar stdout !

???
gokernel

(usa Linux Mint)

Enviado em 25/11/2018 - 12:22h




Pronto parcialmente Resolvido( como eu queria ):


Usei: system ("gcc -v 2>&1");

//-------------------------------------------------------------------
//
// ARQUIVO:
//   redirect.c
//
// COMPILE:
//   redirect.c -o redirect -Wall
//
//-------------------------------------------------------------------
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <io.h>
#include <fcntl.h>
//#include <windows.h>

#define STRING_LEN 50000

char string [STRING_LEN+1];
int out_pipe[2];
int saved_stdout, i;

int main (void) {

    saved_stdout = dup (STDOUT_FILENO); // salva stdout para no final restaurar

    #ifdef WIN32
    if (_pipe (out_pipe, sizeof(string), O_BINARY) != 0 ) {
    #endif
    #ifdef __linux__
    if (pipe(out_pipe) != 0 ) {
    #endif
        exit(1);
    }

    dup2 (out_pipe[1], STDOUT_FILENO); // REdireciona stdout para o pipe
    close (out_pipe[1]);

    // so para testar ...
    system ("gcc -v 2>&1"); //-------------------  LINHA 42  ---------------------

    printf ("HELLO WORLD\n");
    fflush (stdout);

    read (out_pipe[0], string, STRING_LEN); // ler o pipe ... buffer

    dup2 (saved_stdout, STDOUT_FILENO); // restaura stdout para teste
    printf("MY_STRING(\n%s)\n", string);

    return 0;
}
 


Grato Paulo pela ajuda, mas no Windows não tem fork()... ;).

Agora só falta saber como "zerar o string" ... ou limpar o conteúdo do pipe.

Alguém sabe informar como "zerar" o conteúdo do pipe ( "string" ), para quando for usar ( read ) pela segunda ver esse esteja vazio ?

Grato !



5. Re: REdirecionar stdout !

???
gokernel

(usa Linux Mint)

Enviado em 25/11/2018 - 18:18h


Olá Pessoal !!!



O programa completo que me interessa(e funcionando) ficou assim:


//-------------------------------------------------------------------
//
// ARQUIVO:
//   redirect.c
//
// COMPILE:
//   redirect.c -o redirect -Wall
//
//-------------------------------------------------------------------
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <io.h>
#include <fcntl.h>
//#include <windows.h>

#define STRING_LEN 5000

char string [STRING_LEN+1];
char buf [1024];
int out_pipe[2];
int saved_stdout, i;
FILE *fp;

int main (void) {

    saved_stdout = dup (STDOUT_FILENO); // salva stdout para no final restaurar

    #ifdef WIN32
    if (_pipe (out_pipe, sizeof(string), O_BINARY) != 0 ) {
    #endif
    #ifdef __linux__
    if (pipe(out_pipe) != 0 ) {
    #endif
        exit(1);
    }

    dup2 (out_pipe[1], STDOUT_FILENO); // REdireciona stdout para o pipe
    close (out_pipe[1]);

    // so para testar ...
    if ((fp = popen ("gcc -v 2>&1", "r")) != NULL) {
        while (fgets(buf, sizeof(buf), fp) != NULL) {
            //
            //-------------------------------------------------------
            //
            // aqui essa linha nem me interesaa que seja exibida ... so estou exibindo para demonstrar ...
            //
            //-------------------------------------------------------
            //
            printf ("%s", buf); // aqui poderia ja armazenar ( buf ) ...

        }
        pclose(fp);
        printf ("popen aberto\n");
    }

    printf ("HELLO WORLD\n");

    //---------------------------------------------------------------
    // pega a quantidade de letras adicionada em: one
    fflush (stdout);
    int one = read (out_pipe[0], string, STRING_LEN); // ler o pipe ... buffer
    //---------------------------------------------------------------


    // Mais "textos" adicionado ... ADICIONA NO INICIO DO STRING ...

    printf ("segunda linha\n");
    printf ("MAIS UMA LINHA ... testando\n\n");
    //---------------------------------------------------------------
    // pega a SEGUNDA quantidade de letras adicionada em: tow
    fflush (stdout);
    // 43 letras:
    int tow = read (out_pipe[0], string, STRING_LEN); // ler o pipe ... buffer
    //---------------------------------------------------------------

    dup2 (saved_stdout, STDOUT_FILENO); // restaura stdout para teste
    //---------------------------------------------------------------
    // AGORA EXIBE O RESULTADO ... so para testes ...
    //---------------------------------------------------------------
    printf("MY_STRING(\n%s)\n", string);

    printf ("\none: %d, tow: %d\n", one, tow);

    return 0;
}

 


Só fiquei com uma dúvida de o que seria ( 2>&1 ):

    if ((fp = popen ("gcc -v 2>&1", "r")) != NULL) {
    }
 

...
Alguém sabe me responder o que é isso ( 2>&1 ) ? ... isso é novidade para mim !!!

OBS: Só testei no Windows, não sei se no Linux funciona ... depois testarei ...Domingo né !!!

Grato !





6. Re: REdirecionar stdout ! [RESOLVIDO]

Slackjeff
slackjeff

(usa Slackware)

Enviado em 26/11/2018 - 00:55h

Está redirecionando a saida de erros 'STDEER' para a saida padrão 'STDOUT'.

STDEER > STDOUT

I'M ROOT!

Slackware user since ~2008
Meu canal no youtube: 
https://www.youtube.com/SlackJeff

Meu Site:
https://www.slackjeff.com.br/

Meus Programas estão aqui:
https://notabug.org/jeffersonrocha

 







7. Re: REdirecionar stdout ! [RESOLVIDO]

???
gokernel

(usa Linux Mint)

Enviado em 01/12/2018 - 11:09h


Valeu pessoal, grato !







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts