Перенаправить пакетный stderr в файл - PullRequest
10 голосов
/ 28 мая 2009

У меня есть командный файл, который выполняет приложение Java. Я пытаюсь изменить его так, чтобы при возникновении исключения он записывал STDERR в файл.

Это выглядит примерно так:

start java something.jar method %1 %2 2>> log.txt

Есть ли способ, как я могу записать аргументы% 1 и% 2 в файл log.txt? Я не хочу записывать его в файл журнала каждый раз, когда вызывается этот пакетный файл, только при возникновении исключения.

Я пытался найти способ перенаправить STDERR в переменную, но я не мог понять это. В идеале я хотел бы, чтобы файл журнала выглядел примерно так:

Batch file called with parameters:
- "first arg"
- "second arg"
Exception: 
java.io.exception etc...

------------------------------------

Batch file called with parameters:
- "first arg"
- "second arg"
Exception: 
java.io.exception etc...

Ответы [ 6 ]

3 голосов
/ 25 августа 2009

Примерно так может работать:

javastart.cmd

@echo off
set params=%*
for /f "delims=" %%e in ('java something.jar method %1 %2 ^>nul') do (
    echo Batch file called with parameters:>>log.txt
    echo - Args[]: %*>>log.txt
    echo - Arg[1]: %1>>log.txt
    echo - Arg[2]: %2>>log.txt
    echo Exception: %%e
)

Я сам не программист Java, я не могу проверить этот вывод / ситуацию, но:

1: % * означает все параметры, от 1-го до последнего (даже% 12, хотя он не доступен напрямую), независимо от форматирования. Может быть, лучше использовать это, чем разграничивать их. Даже при плохом интервале / цитировании у вас также будут полные параметры. Я добавил строку в журнал, чтобы показать полную строку, а затем параметры. Вы можете увидеть, где была проблема, если речь идет о плохих аргументах.

2: отправка stdout на ноль (^> nul) будет сохранять только вывод stderr, установленный в %% e

3: То, что находится в части do , произойдет только в том случае, если в тестовом операторе for фактически есть что-либо в качестве вывода, т.е. если % % e установлено.

С учетом сказанного вы должны протестировать скрипт и посмотреть, действительно ли исключение отправляется в stderr или, как некоторые другие программы, в stdout, даже если произошла ошибка.

Надеюсь, это поможет.

2 голосов
/ 28 мая 2009

Единственное работающее решение, которое я вижу, это перенаправить stderr во временный файл

java blah.jar %1 %2 2>stderr

, а затем посмотреть, было ли что-то записано в файл и записать в журнал в этом случае.

for %%i in (stderr) do if %%~zi GTR 0 (
    echo Parameters: %1 %2 >>log.txt
    type stderr >> log.txt
)

Если пакеты выполняются не по порядку, а одновременно, вам нужно найти что-то, что может изменить временную переменную:

set file=%time::=%
set /a file=file
set file=%file%%random%
java blah.jar %1 %2 2>stderr_%file%
for %%i in (stderr) do if %%~zi GTR 0 (
    echo Parameters: %1 %2 >>log.txt
    type stderr >> log.txt
)

Это позволит избежать столкновений между несколькими запущенными партиями. Однако в настоящее время вы ничего не используете для блокировки записи в ваш файл журнала, и вещи могут выглядеть неуместно, когда в него записываются другие вещи (в других пакетах вы можете получить чередование в командах echo и type или, когда вы также перенаправляете вывод java в этот файл, тогда он может смешаться с обычным выводом программы java:

Parameters: foo bar
Some regular output
Parameters: foo2 bar2
More output
NullPointerException at Blah: What we really wanted to have right after the parameters
IOException at Blah: This exception belongs to the parameters foo2 bar2

Вы можете использовать другой файл в качестве семафора для записи в журнал, чтобы избежать смешивания пакетных выходов: создайте файл [copy nul file], когда вы хотите записать в журнал, затем удалите его и прежде чем пытаться создать его проверьте, действительно ли он там, и подождите, пока он не исчезнет. Однако вы ничего не можете сделать, чтобы журнал stdout смешивался с файлом, за исключением того, что вы используете подход временного файла и для stdout (и просто type для журнала stdout до log.txt, когда Java-программа завершилась, но, снова с использованием семафора.

2 голосов
/ 28 мая 2009

Я не понимаю, что вы спрашиваете, но вот некоторая информация, которая может помочь ...

Вы можете перенаправить stderr отдельно от stdout в файле .cmd или .bat. Чтобы перенаправить stderr, используйте что-то вроде этого:

MyCommand.exe > command.stdout.txt  2> command.stderr.txt

Затем вы можете проверить содержимое файла command.stderr.txt, и, если он есть, объединить его с command.stdout.txt в файле журнала. Или вы могли бы согласовать это в любом случае. Если вам нравится, вы можете также повторить команду, которую вы запустили, в окончательный файл журнала.

Вы также можете проверить код завершения в командном файле, используя% ERRORLEVEL% env var. Ожидается, что для exe-файлов будет установлено значение ERRORLEVEL в случае ошибки. Я не знаю, делает ли java.exe это. Должен, если он хороший гражданин на Windows. Это может быть альтернативный способ выяснить, завершилось ли приложение Java с ошибкой. Но это не гарантия, что stderr ничего не получил. Например, приложение Java может распечатать исключение и трассировку стека, а затем завершить работу с кодом 0, который указывает на успех. В этом случае stderr должен был бы скопить его, но ERRORLEVEL был бы равен нулю.

РЕДАКТИРОВАТЬ : s / ERROR_LEVEL / ERRORLEVEL

0 голосов
/ 12 июня 2009

Пакетный файл, как это должно сделать свое дело.

start_prog.cmd

CALL :Start_Prog arg1 arg2
GOTO :EOF

:Start_Prog
    something.py %1 %2 2>&1 1>nul | "C:\Python26\python.exe" format_output.py %1 %2 >>log.txt
    GOTO :EOF

Здесь я передаю stderr через канал и передаю аргументы в качестве аргументов. Затем вывод добавляется в файл log.txt.

Выбросить стандартный вывод

1>nul

Перенаправить stderr на стандартный вывод

2>&1

Передача stderr в скрипт для форматирования вывода и передачи аргументов в качестве аргументов.

| "C:\Python26\python.exe" format_output.py %1 %2

Добавить вывод к "log.txt" .

>>log.txt

В моей системе мне нужно вызвать python.exe, иначе канал не работает.

Вот два файла, которые я использовал "thing.py " и " format_output.py ".

something.py

import sys
print >>sys.stdout, " ".join(sys.argv[1:])
print >>sys.stderr, "java.io.exception etc..."

format_output.py

import sys

print "Batch file called with parameters:"
for arg in sys.argv[1:]:
    print '- "{0}"'.format(arg)

print "Exception:"
for line in sys.stdin:
    print line

И, наконец, вот вывод.

log.txt

Batch file called with parameters:
- "arg1"
- "arg2"
Exception:
java.io.exception etc...

Единственное, чего не хватает, так это того, что что-то всегда записывается в файл "log.txt" .

Чтобы привести это в порядок, я бы переместил запись файла журнала в "format_output.py" .

Затем вы можете добавить проверку, чтобы проверить, является ли stderr из вашей программы пустым.

0 голосов
/ 28 мая 2009

Попробуйте использовать ОШИБКА

java something.jar method %1 %2 2>> log.txt
IF %ERRORLEVEL% NEQ 0 GOTO Error

Error:
@ECHO There was an error
@ECHO Arg 1: %1 >> log.txt
@ECHO Arg 2: %2 >> log.txt
0 голосов
/ 28 мая 2009

Как на счет этого (не проверено):

@echo off
@echo Batch file called with parameters: >> log.txt
@echo - %1 >> log.txt
@echo - %2 >> log.txt
start java something.jar method %1 %2 2>> log.txt
...