2012-08-14 16 views
5

Tengo una serie de líneas en un archivo por lotes (.bat) que se ejecuta en una máquina Windows, por ejemplo:salida de redirección de DOS si hay salida

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

veces proj.exe devuelve nada (vacío) en lugar de datos útiles. En esos casos, no quiero generar un archivo de texto, ¿es esto algo fácilmente realizable en el lado del archivo por lotes? El comportamiento actual es que siempre se crea un archivo de texto, en el caso de salida vacía, es solo un archivo en blanco.

+2

Justo [eliminar todos los archivos con longitud cero] [1]. Puede intercalar esos comandos con los comandos de "inicio". Es decir. algo así como: [1]: http://stackoverflow.com/questions/4176962/recursively-delete-0kb-files-using-windows-cmd – jpe

+0

@jpe - esa parece la única respuesta posible si quieres manejarlo completamente en DOS. Debe publicarlo como una respuesta para que pueda marcarse como "correcto". –

+0

Stack Overflow cambió mi respuesta en un comentario porque era demasiado corta. Así que elaboré un poco :) – jpe

Respuesta

4

La solución jpe requiere que su lote principal sepa cuándo se han completado los procesos iniciados antes de que pueda verificar los tamaños del archivo de salida. Puede usar la opción START/WAIT, pero luego pierde la ventaja de correr en paralelo.

Puede utilizar el hecho de que la redirección a un archivo fallará si otro proceso ya ha redirigido la salida a ese mismo archivo. Cuando su lote principal puede redirigir a ellos con éxito, entonces sabrá que todos los procesos iniciados se han completado.

Probablemente debería redirigir stderr al archivo de salida, así como la salida estándar

@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' es' 0', 'stdout' es' 1', 'stderr' es' 2'. Por curiosidad, ¿qué significa la parte '9' de' 9 >> %% F ('do? –

+0

Es el manejador de archivo no utilizado con el número más alto disponible para CMD.EXE. Se crea el archivo y cualquier salida que se envíe a ese identificador de archivo terminará en el archivo, pero por supuesto nada irá allí en circunstancias normales. Debería funcionar con cualquiera de los identificadores de archivo 1 a 9, pero solo estaba siendo cauteloso. – dbenham

2

Solo delete all files with zero length. Editar: para acomodar el hecho de que start sin la bandera/ESPERA retornos antes de esperar el prog.exe para terminar, se podría crear el siguiente guión envoltorio progwrapper.bat para su prog.exe:

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

luego llamar a la envoltura de su script principal:

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

etc.

Si PROG.EXE es una aplicación de interfaz gráfica de usuario, entonces debería haber un start /B /WAIT prog.exe en el progwrapper.bat.

+1

Esto funciona, el único problema es que tendría que poner una bandera '/ wait' en mi' inicio' porque de lo contrario trataría de eliminar antes de que se generen. – user17753

+0

@ user17753 - Sí, su lote padre debería saber cuándo verificar el tamaño del archivo. Estoy trabajando en una respuesta que permita que múltiples programas se ejecuten en paralelo y no verifique los tamaños hasta que todos estén completos. – dbenham

Cuestiones relacionadas