2013-04-21 6 views
7

Ho il codice sotto quello rimando il filo sul here utilizzare la funzionecomando linux esecuzione con popen sul codice C

int main(int argc,char *argv[]){  
    FILE* file = popen("ntpdate", "r"); 
    char buffer[100]; 
    fscanf(file, "%100s", buffer); 
    pclose(file); 
    printf("buffer is :%s\n", buffer); 
    return 0; 
} 

popen Produce:

21 Apr 03:03:03 ntpdate[4393]: no server can be used, exiting 
buffer is: 

perché printf non emette nulla? Se utilizzo ls come comando, printf restituisce l'output ls. cosa sto facendo male nell'esecuzione di ntpdate?

Se eseguo il codice qui sotto (riferendosi alla webpage)

#define COMMAND_LEN 8 
#define DATA_SIZE 512 

int main(int argc,char *argv[]){ 


    FILE *pf; 
     char command[COMMAND_LEN]; 
     char data[DATA_SIZE]; 

     // Execute a process listing 
     sprintf(command, "ntpdate"); 

     // Setup our pipe for reading and execute our command. 
     pf = popen(command,"r"); 

     if(!pf){ 
     fprintf(stderr, "Could not open pipe for output.\n"); 
     return; 
     } 

     // Grab data from process execution 
     fgets(data, DATA_SIZE , pf); 

     // Print grabbed data to the screen. 
     fprintf(stdout, "-%s-\n",data); 

     if (pclose(pf) != 0) 
      fprintf(stderr," Error: Failed to close command stream \n"); 

     return 0; 
} 

ottengo

21 Apr 03:15:45 ntpdate[5334]: no servers can be used, exiting 
-�2}�����"|�4#|�- 
Error: Failed to close command stream 

quali sono torti sui codici di cui sopra?

+1

Se facciamo 'ntpdate 2>/dev/null' possiamo vedere che sta usando' stderr' quindi è necessario per reindirizzare 'stderr' per vedere l'output –

risposta

14

Dato che l'uscita sta per stderr è necessario reindirizzare stderr in questo modo:

FILE* file = popen("ntpdate 2>&1", "r"); 

questo reindirizzerà stderr a stdout e così si vedrà l'uscita da entrambi. Secondo numero fscanf si fermerà al primo spazio in modo da poter sostituire con fgets:

fgets(buffer, 100, file); 
+0

emette solo' buffer is: 21' qui, i server sono definiti su '/ etc/ntp.conf'. se uso 'FILE * file = popen (" ntpdate 79.99.6.190 2> & 1 "," r ");' che 79.99.6.190 è un server ntp di http://www.pool.ntp.org/. mi sto perdendo qualcosa? questo è esattamente il modo in cui utilizzo il codice http://pastebin.com/8g77zRF0 – sven

+0

Mi chiedo se funzioni bene dalla tua parte? – sven

+0

@sven risposta appena aggiornata, ho perso il problema fscanf –

2

Come Shafik Yaghmour correttamente diagnosticato, l'output visualizzato da ntpdate viene scritto (correttamente) sul suo errore standard, che è lo stesso dell'errore standard del programma.

per ottenere i messaggi di errore inviati giù per il tubo, utilizzare:

FILE *file = popen("ntpdate 2>&1", "r"); 

che invia l'output di errore standard dal ntpdate sullo standard output del comando, che è il tubo che stai leggendo.

Ovviamente, l'utilizzo di ntpdate non funzionerà correttamente fino a quando non avrai configurato qualcosa.

1
FILE *popen(const char *command, const char *type); 
+1

Ciao nitai, benvenuto [così]. Perché scrivi la stessa riga due volte? Puoi spiegare la tua risposta in modo che possa essere più utile per gli altri? Puoi aggiornare la tua risposta cliccando sul link * [modifica] * sotto il post. Grazie. – Pang