|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
[C] Eseguire popen senza visualizzare l'output
Ciao.
Devo implementare il meccanismo delle pipe comportandosi come si comporta la shell di Linux. Ho pensato che si potesse usare la funzione popen per ogni comando da eseguire nella pipe. Il problema è che non so quale potrebbe essere un modo per eseguire un comando senza visualizzare il suo output. Cioè deve far vedere l'output solo dell'ultimo comando nella catena di comandi nella pipe e quindi degli altri no. Come posso fare? Grazie. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Quello ci sono riuscito. Praticamente ho redirezionato l'STDOUT sulla struttura FILE * della pipe prima di chiamare la popen. Ora mi servirebbe capire come visualizzare l'output dell'ultimo comando (a seguito dei comandi eseguiti in precedenza).
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Nessuno sa rispondere?
|
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Apr 2004
Messaggi: 130
|
L'idea di base è questa:
Codice:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
int p[2];
pid_t pid;
char *c1[] = {"ls", "-l", NULL};
char *c2[] = {"head", "-n", "1", NULL};
if (pipe(p) < 0) {
perror("pipe()");
exit(EXIT_FAILURE);
}
if ((pid = fork()) < 0) {
perror("fork()");
exit(EXIT_FAILURE);
}
if (pid == 0) {
close(p[0]);
dup2(p[1], STDOUT_FILENO);
close(p[1]);
execvp(c1[0], c1);
perror("execvp()");
_exit(EXIT_FAILURE);
}
if ((pid = fork()) < 0) {
perror("fork()");
exit(EXIT_FAILURE);
}
if (pid == 0) {
close(p[1]);
dup2(p[0], STDIN_FILENO);
close(p[0]);
execvp(c2[0], c2);
perror("execvp()");
_exit(EXIT_FAILURE);
}
close(p[0]);
close(p[1]);
wait(NULL);
wait(NULL);
return 0;
}
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Ok, grazie. Ma avendo più processi da mettere in pipe come faccio ogni volta a fare quelle redirezioni? E attraverso popen come faccio a fargli avere un comportamento simile? Con popen non riesco ancora a capire quando bisogna mettere il flag r e quando quello w.
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Mar 2004
Messaggi: 1455
|
Quote:
__________________
Ciao ~ZeRO sTrEsS~ |
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
L'ho già letta la man di pipe. Il problema rimane. Ripeto non capisco con popen quando bisogna mettere il flag r e quando quello w. Per quanto riguarda le pipe "normali" create tramite la funzione pipe() le ho capite.
|
|
|
|
|
|
#8 |
|
Member
Iscritto dal: Apr 2004
Messaggi: 130
|
La popen() restituisce uno stream unidirezionale, in lettura (r) o in scrittura (w).
Codice:
goku@nig:/tmp$ cat ptest.c && ./ptest && cat ptest.txt
#include <stdio.h>
int main(void)
{
FILE *in, *out;
char buffer[1024];
int c = 1;
in = popen("cat ptest.c", "r");
out = popen("cat >ptest.txt", "w");
while (fgets(buffer, sizeof buffer, in))
fprintf(out, "%2d: %s", c++, buffer);
pclose(in);
pclose(out);
return 0;
}
1: #include <stdio.h>
2:
3: int main(void)
4: {
5: FILE *in, *out;
6: char buffer[1024];
7: int c = 1;
8:
9: in = popen("cat ptest.c", "r");
10: out = popen("cat >ptest.txt", "w");
11: while (fgets(buffer, sizeof buffer, in))
12: fprintf(out, "%2d: %s", c++, buffer);
13: pclose(in);
14: pclose(out);
15:
16: return 0;
17: }
goku@nig:/tmp$
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Ok, grazie. Però non capisco ancora una cosa. Cioè io eseguo il primo comando con popen, poi se ho lo stream è in sola lettura o in sola scrittura a me poco importa, perché come faccio a dirgli al prossimo comando che l'input si trova proprio in quello stream. Per fare questo posso eseguire una write di quello stream sullo STANDARD INPUT?
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Ok, per quello che devo fare io mi hanno detto i miei prof. che la popen non va usata
Codice:
dup2(p[1], STDOUT_FILENO); close(p[1]); |
|
|
|
|
|
#11 | |||
|
Member
Iscritto dal: Apr 2004
Messaggi: 130
|
Quote:
Quote:
Quote:
|
|||
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Mar 2004
Messaggi: 1455
|
Quote:
Redirezioni p[1] allo STDOUT, e poi chiudi p[1].
__________________
Ciao ~ZeRO sTrEsS~ |
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Ok, spero di aver capito. Grazie.
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
E se io poi voglio fare in modo che l'STDOUT mi ristampi l'output su schermo come faccio?
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Trovato il modo
Basta che redireziono p[0] su STDIN. Ora ho un piccolo problema (ho quasi finito Codice:
for(i=1; i<res; ++i){
if((pid = fork()) < 0){
perror("fork error");
exit(FORK_ERR);
}
if(pid == 0){
if(args!=NULL){
free(args);
args=NULL;
}
args=(char **)calloc(MAX_ARGS,sizeof(char *));
if(do_I_launch_parse(commands[i]) == 1)
parse(commands[i],args);
if(i==res-1){
close(p[1]);
if(dup2(p[0],STDIN_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
close(p[0]);
}
else{
if(dup2(p[0],STDIN_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
if(dup2(p[1],STDOUT_FILENO) == -1){
perror("dup error");
exit(DUP_ERR);
}
close(p[0]);
close(p[1]);
}
((args[0]==NULL) ? execlp(commands[i],commands[i],NULL) : execvp(commands[i],args));
perror("exec failed");
exit(EXEC_ERR);
}
if(pid > 0){
if (waitpid(pid,&status,0) == -1){
if(errno!=EINTR){
perror("waitpid error");
exit(WAIT_ERR);
}
else{
kill(pid,SIGTERM);
do{
if (waitpid(pid,&status,0) != -1)
break;
}while(errno==EINTR);
}
}
}
}
Grazie. |
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Jan 2001
Città: Villanova di Guidonia (RM)
Messaggi: 1079
|
Per favore, se riesco a risolvere quest'ultimo problema ho praticamente finito tutto.
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:43.



















