2012-08-14 12 views
5

Mam szereg linii w pliku wsadowym (.bat) uruchomiony na komputerze z systemem Windows, na przykład:DOS Przekierowanie wyjścia, jeśli istnieje wyjście

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

Czasami proj.exe nic nie zwraca (pusty) zamiast użytecznych danych. W takich przypadkach nie chcę generować pliku tekstowego, czy jest to łatwe do wykonania po stronie pliku wsadowego? Obecne zachowanie jest to, że plik tekstowy jest zawsze tworzony, w przypadku pustego wyjścia jest to po prostu pusty plik.

+2

Wystarczy [usunąć wszystkie pliki z zerowej długości] [1]. Polecenia "start" można przeplatać za pomocą poleceń "start". To znaczy. coś takiego: [1]: http://stackoverflow.com/questions/4176962/recursively-delete-0kb-files-using-windows-cmd – jpe

+0

@jpe - to wydaje się być jedyną możliwą odpowiedzią, jeśli chcesz obsłużyć go w całości w DOS. Powinieneś opublikować ją jako odpowiedź, aby mogła być oznaczona jako "poprawna". –

+0

Stack Overflow zmienił moją odpowiedź na komentarz, ponieważ była za krótka. Więc opracowałem nieco :) – jpe

Odpowiedz

4

Rozwiązanie jpe wymaga od rodzica wsadu, aby wiedzieć, kiedy rozpoczęte procesy zostały zakończone, zanim będzie można sprawdzić rozmiary plików wyjściowych. Możesz użyć opcji START/WAIT, ale stracisz przewagę równoległego działania.

Możesz użyć faktu, że przekierowanie do pliku nie powiedzie się, jeśli inny proces już przekierował dane wyjściowe do tego samego pliku. Kiedy twoja nadrzędna grupa może przekierować do nich z powodzeniem, wiesz, że wszystkie rozpoczęte procesy zostały zakończone.

Prawdopodobnie powinien przekierować stderr do pliku wyjściowego, jak i 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' to' 0', 'stdout' to' 1', 'stderr' to' 2'. Z ciekawości, co robi '9' część' 9 >> %% F ('do? –

+0

Jest to najwyższy numerowany nieużywany uchwyt pliku dostępny dla CMD.EXE.Ten plik jest tworzony i wszelkie dane wyjściowe wysyłane do ten plik dojdzie do pliku, ale oczywiście nic nie będzie się tam działo w normalnych okolicznościach.Należy pracować z jednym z uchwytów plików 1-9, ale byłem po prostu ostrożny. – dbenham

2

Po prostu delete all files with zero length. Edit: aby pomieścić fakt start bez zwrotów/wait flag przed czekając na prog.exe do rozwiązania, można utworzyć następujący skrypt otoki progwrapper.bat dla prog.exe:

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

Następnie zadzwonić opakowanie ze skryptu głównego:

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

itp

Jeśli prog.exe to aplikacja GUI, to trzeba mieć start /B /WAIT prog.exe w progwrapper.bat.

+1

To działa, tylko problem polega na tym, że musiałbym umieścić flagę '/ wait' na moim' start' ', ponieważ w przeciwnym razie spróbowałbym usunąć zanim zostały wygenerowane. – user17753

+0

@ user17753 - Tak, twoja przesyłka nadrzędna będzie musiała wiedzieć, kiedy sprawdzić rozmiar pliku. Pracuję nad odpowiedzią, która umożliwi równoległe działanie wielu programów i nie będzie sprawdzać rozmiarów, dopóki wszystkie nie będą kompletne. – dbenham

Powiązane problemy