Domanda

Come posso avviare un'app e acquisire l'output tramite stdout e forse stderr?

Sto scrivendo un sistema di compilazione automatizzato e devo acquisire l'output da analizzare. Vorrei aggiornare il repository svn e afferrare il numero di revisione in modo da poter spostare i file in autobuild / revNumber / in caso di successo. Vorrei anche compilare usando make e caricare il testo di compilazione sul mio server affinché tutti possano vedere gli avvertimenti e gli errori su una build fallita.

Non riesco a trovare la funzione system () , ma ho trovato la funzione CreateProcess () su MSDN. Sono in grado di lanciare ciò di cui ho bisogno ma non ho idea di come catturare lo stderr e lo stdout. Noto che il processo si avvia separatamente a meno che non imposti un punto di interruzione e mantenga la mia app in uscita, che manterrà quindi tutto il testo nella finestra della mia console dell'app. Vorrei anche aspettare fino al termine di tutti i processi e quindi eseguire la scansione dei dati prodotti per eseguire qualsiasi operazione aggiuntiva di cui ho bisogno. Come posso fare tutto questo?

È stato utile?

Soluzione

Nelle conchiglie reali (che significa, non conchiglie di mare - voglio dire, non in C Shell o suoi derivati), quindi:

program arg1 arg2 >/tmp/log.file 2>&1

Esegue il programma con gli argomenti forniti e reindirizza lo stdout su /tmp/log.file; la notazione ( geroglifico ) ' 2 > & amp; 1 ' alla fine invia stderr (descrittore di file 2) nello stesso posto in cui sta andando stdout (descrittore di file 1). Si noti che la sequenza delle operazioni è importante; se li invertite, l'errore standard andrà a destinazione dell'output standard e quindi l'output standard (ma non l'errore standard) verrà reindirizzato al file.

La scelta del nome del file mostrato è terribile per numerosi motivi: dovresti consentire all'utente di scegliere la directory e probabilmente includere l'ID del processo o il timestamp nel nome del file.

LOG=${TMPDIR:-/tmp}/log.$.$(date +%Y%m%d-%H%M%S)
program arg1 arg2 >$LOG 2>&1

In C ++, è possibile utilizzare la funzione system () (ereditata da C) per eseguire i processi. Se devi conoscere il nome del file nel programma C ++ (plausibile), quindi genera il nome nel programma ( strftime () è tuo amico) e crea la stringa di comando con quel nome file. (Rigorosamente, è necessario anche getenv () per ottenere $ TMPDIR e la funzione POSIX getpid () per ottenere l'ID processo, quindi è possibile simulare la doppia riga script di shell (anche se il PID usato sarebbe del programma C ++, non della shell avviata).

È possibile invece utilizzare la funzione POSIX popen () ; dovresti includere la notazione ' 2 > & amp; 1 ' nella stringa di comando che crei per inviare l'errore standard del comando nella stessa posizione dell'output standard, ma non è necessario un file temporaneo:

FILE *pp = popen("program arg1 arg2 2>&1", "r");

È quindi possibile leggere il flusso di file. Non sono sicuro che esista un modo semplice per mappare un flusso di file C in un istream C ++; probabilmente c'è.

Altri suggerimenti

Devi riempire la struttura STARTUP_INFO, che ha hStdInput, hStdOutput e hStdError. Ricorda di ereditare gli handle quando CreateProcess.

/* Assume you open a file handle or pipe called myoutput */
STARTUP_INFO si_startinfo;
ZeroMemory(&si_startinfo, sizeof(STARTUP_INFO));
si_startinfo.cb = sizeof(STARTUP_INFO);
si_startinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si_startinfo.hStdOutput = myoutput;
si_startinfo.hStdError = myoutput;
si_startifno.dwFlags != STARTF_USEHANDLES;

PROCESS_INFORMATION pi_procinfo;
ZeroMemory(&pi_procinfo, sizeof(PROCESS_INFORMATION);

CreateProcess(NULL, cmdline, NULL, NULL, true, 0, NULL, pathname, &si_startinfo, &pi_procinfo);

Non ho mostrato gli aspetti di gestione degli errori, che dovrai fare. Il quinto argomento è impostato su true per ereditare gli handle. Altri hanno spiegato come creare pipe in modo che non lo ripeterò qui.

I CRT di Microsoft e la libreria MSDN includono la funzione di sistema e la funzione _popen.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top