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