Salve.
Ho un piccolo quesito. Ho un semplice programmino C/C++ in Linux che, prendendo come argomenti una linea di comando per la shell la esegue tramite la exec (in particolar modo, io utilizzo la execvp, ma penso che i ragionamenti valgano anche per le altre funzioni della famiglia delle exec). Il mio programmino è il seguente:
codice:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
int main(int argc, char *argv[])
{
cout << getpid() << ") Sono il processo " << getpid() << endl;
int pid=vfork();
if (pid<0)
return -1;
else if (pid==0)
{
execvp(argv[1], argv+1);
perror("execvp");
return -1;
}
int status;
cout << getpid() << ") Mio figlio ha pid " << pid << endl;
wait(&status);
cout << getpid() << ") Mio figlio " << pid << " è terminato!" << endl;
return 0;
}
Supponendo che il mio programma compilato si chiamasse ./esegui, se eseguissi ad esempio:
Mi stamperebbe tranquillamente a video tutti i processi in esecuzione nel mio sistema (e similmente farebbe se volessi eseguire altri comandi), ed in più aggiunge le semplici righe di servizio dei miei cout (non cambierebbe assolutamente nulla se anziché i cout del C++ usassi i printf rendendo il programma un programma C puro).
Tuttavia, se volessi usare un comando con pipe, ad esempio ps -aux | grep "bash", comincerebbero ad esserci problemi. Infatti se faccio:
codice:
./esegui ps -aux | grep "bash"
Mi stampa sì tutti i processi, ma non le righe di servizio che avevo aggiunto io con i cout, in quanto non comprendono la parola "bash". Infatti il comando viene interpretato come se la prima parte da eseguire fosse ./esegui ps -aux e come se il comando grep dovesse prendere in input tutto l'output di ./esegui ps -aux e non solo quello di ps -aux (non so se mi sono spiegato).
Non so se ci sono modi per far capire che il comando da passare ad esegui (e quindi alla execvp) è tutto ps -aux | grep "bash". Per ora ho provato a fare così:
codice:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
int main(int argc, char *argv[])
{
cout << getpid() << ") Sono il processo " << getpid() << endl;
char* cmd[]={"ps","-aux","|","grep","\"bash\"",(char*)NULL};
int pid=vfork();
if (pid<0)
return -1;
else if (pid==0)
{
execvp("ps", cmd);
perror("execvp");
return -1;
}
int status;
cout << getpid() << ") Mio figlio ha pid " << pid << endl;
wait(&status);
cout << getpid() << ") Mio figlio " << pid << " è terminato!" << endl;
return 0;
}
Tuttavia, eseguendo ./esegui ottengo addirittura un errore in esecuzione.
Non è proprio possibile passare l'operatore pipe "|" ad una funzione di tipo exec? :master: