2012-08-14 14 views
5

ho una serie di linee in un file batch (.bat) in esecuzione su una macchina Windows, ad esempio:uscita reindirizzamento DOS se non v'è uscita

start /b prog.exe cmdparam1 cmdparam2 > test1.txt 
start /b prog.exe cmdparam1 cmdparam2 > test2.txt 

volte proj.exe restituisce nulla (vuoto) invece di dati utili. In quei casi, non voglio generare un file di testo, è qualcosa di facilmente realizzabile sul lato del file batch delle cose? Il comportamento attuale è che viene sempre creato un file di testo, nel caso di output vuoto è solo un file vuoto.

+2

Basta [eliminare tutti i file con lunghezza zero] [1]. È possibile interlacciare quei comandi con i comandi "start". Cioè qualcosa di simile: [1]: http://stackoverflow.com/questions/4176962/recursively-delete-0kb-files-using-windows-cmd – jpe

+0

@jpe - che sembra l'unica risposta possibile, se si desidera gestirlo interamente in DOS. Dovresti postarlo come risposta in modo che possa essere contrassegnato come "corretto". –

+0

Stack Overflow ha modificato la mia risposta in un commento perché era troppo breve. Così ho elaborato un po ':) – jpe

risposta

4

Il jpe richiede il batch genitore per sapere quando i processi avviati hanno completato prima che possa controllare le dimensioni dei file di output. Puoi usare l'opzione START/WAIT, ma poi perdi il vantaggio di correre in parallelo.

È possibile utilizzare il fatto che il reindirizzamento a un file fallirà se un altro processo è già reindirizzato uscita per lo stesso file. Quando il tuo gruppo principale può reindirizzare a loro con successo, allora sai che i processi avviati sono stati completati.

Probabilmente è opportuno reindirizzare stderr al file di output così come stdout

@echo off 

::start the processes and redirect the output to the ouptut files 
start /b "" cmd /c prog.exe cmdparam1 cmdparam2 >test1.txt 2>&1 
start /b "" cmd /c prog.exe cmdparam1 cmdparam2 >test2.txt 2>&1 

::define the output files (must match the redirections above) 
set files="test1.txt" "test2.txt" 

:waitUntilFinished 
:: Verify that this parent script can redirect an unused file handle to the 
:: output file (append mode). Loop back if the test fails for any output file. 
:: Use ping to introduce a delay so that the CPU is not inundated. 
>nul 2>nul ping -n 2 ::1 
for %%F in (%files%) do (
    9>>%%F (
    rem 
) 
) 2>nul || goto :waitUntilFinished 

::Delete 0 length output files 
for %%F in (%files%) do if %%~zF==0 del %%F 
+0

'stdin' è' 0', 'stdout' è' 1', 'stderr' è' 2'. Per curiosità, cosa fa la parte '9' di' 9 >> %% F ('do? –

+0

È l'handle di file inutilizzato numerato più alto disponibile per CMD.EXE. Il file viene creato e qualsiasi output che viene inviato a quell'handle di file finirà nel file, ma ovviamente non ci sarà mai nulla in circostanze normali, dovrebbe funzionare con qualsiasi handle di file da 1 a 9, ma stavo solo facendo attenzione. – dbenham

2

Proprio delete all files with zero length. Edit: per ospitare fatto che start senza le/bandiera WAIT restituisce prima di attendere il prog.exe per terminare, è possibile creare il seguente script wrapper progwrapper.bat per il prog.exe:

prog.exe "%1" "%2" > "%3" 
if %~z3==0 del "%3" 

quindi chiamare l'involucro dal vostro script maestro:

start /b progwrapper.bat cmdparam1 cmdparam2 > test1.txt 
start /b progwrapper.bat cmdparam1 cmdparam2 > test2.txt 

ecc

Se PROG.EXE è un'applicazione GUI, allora si dovrebbe avere un start /B /WAIT prog.exe nel progwrapper.bat.

soluzione
+1

Questo funziona, unico problema è che avrei dovuto mettere in una bandiera '/ wait' sulle mie' start's perché altrimenti mi piacerebbe provare a eliminare prima che sono stati generati. – user17753

+0

@ user17753 - Sì, il gruppo principale dovrebbe sapere quando controllare la dimensione del file. Sto lavorando a una risposta che consentirà a più programmi di funzionare in parallelo e di non controllare le dimensioni finché non sono state completate tutte. – dbenham