Search code examples
batch-filedos

Redirect DOS Output Only if there is Output


I have a series of lines in a batch file (.bat) running on a Windows machine, e.g.:

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

Sometimes proj.exe returns nothing (empty) instead of useful data. In those cases I want to not generate a text file, is this something easily doable on the batch file side of things? The current behavior is that a text file is always created, in the case of empty output it's just a blank file.


Solution

  • The jpe solution requires your parent batch to know when the started processes have completed before it can check the output file sizes. You can use the START /WAIT option, but then you lose the advantage of running in parallel.

    You can use the fact that redirection to a file will fail if another process has already redirected output to that same file. When your parent batch can redirect to them successfully then you know the started processes have all completed.

    You probably should redirect stderr to your output file as well as 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