2009-05-28 13 views
10

Tengo un archivo por lotes que ejecuta una aplicación java. Intento modificarlo para que cada vez que se produzca una excepción, escriba el STDERR en un archivo.Redirigir lote stderr al archivo

se ve algo como esto:

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

¿Hay alguna manera de escribir el argumento% 1 y 2% en el fichero log.txt así? No deseo escribirlo en el archivo de registro cada vez que se llame a este archivo por lotes, solo cuando se produce una excepción.

Intenté buscar una forma de redirigir STDERR a una variable, pero no pude resolverlo. Lo ideal sería el archivo de registro a ser algo como:

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... 

Respuesta

0

¿Qué tal algo como esto (no probado):

@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 
+0

Pero eso registraría la salida cada vez que se llamara al archivo por lotes, ¿no es así? Me gustaría evitar eso si es posible y simplemente hacer que inicie sesión si la aplicación java arroja una excepción. – nivlam

2

que no entiendo exactamente lo que están pidiendo, pero aquí hay algo de información que puede ayudar ...

Puede redirigir stderr por separado de stdout en un archivo .cmd o .bat. Para redirigir stderr, usar algo como esto:

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

A continuación, se puede comprobar la command.stderr.txt para el contenido, y si alguno está presente, concatenarlo a la command.stdout.txt en su archivo de registro. O podrías usarlo en cualquier caso. Si lo desea, también podría repetir el comando que ejecutó, en el archivo de registro final.

También puede verificar el código de salida en un archivo por lotes, utilizando% ERRORLEVEL% env var. Se espera que los archivos Exe configuren ERRORLEVEL en caso de error. No sé si java.exe hace esto. Debería, si es un buen ciudadano en Windows. Esta podría ser una forma alternativa de averiguar si la aplicación Java salió con una condición de error. Pero esto no es garantía de que stderr no tenga nada. Por ejemplo, una aplicación Java puede imprimir una excepción y un seguimiento de pila, y luego salir con el código 0, que indica éxito. En cuyo caso, stderr tendría suciedad en él, pero ERRORLEVEL sería cero.

EDITAR: s/error_level/ERRORLEVEL

+0

Estoy tratando de evitar escribir en un archivo cada vez que se llama a este archivo por lotes. Este archivo por lotes se llama con mucha frecuencia y vive en un servidor ya saturado IO. – nivlam

+0

Lea mal su respuesta un poco. Ya estoy escribiendo el stderr en un archivo de registro, pero también quiero intentar escribir los parámetros que pasaron al archivo por lotes. Solo quiero registrar estos parámetros cuando escribe stderr en el registro. – nivlam

+0

Se llama% ERRORLEVEL%, no% ERROR_LEVEL%. Además, debe verificarlo con "if errorlevel 1 ..." que no se compara con% errorlevel% que en realidad no existe. – Joey

0

Trate de usar ERRORLEVEL

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

Acabo de probar esto y errorlevel siempre es cero, incluso cuando Java arroja una excepción. – nivlam

+0

Si la clase principal de Java está escrita por usted, puede envolver todo en un try/catch y usar exit (1) en catch block para establecer el nivel de error en el entorno –

2

La única solución a trabajar veo sería redirigir stderr a un archivo temporal

java blah.jar %1 %2 2>stderr 

y luego busca si algo se ha escrito en el archivo y escribiendo en el registro en ese caso.

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

Si los lotes no se ejecutan de forma secuencial, sino más bien al mismo tiempo que necesita para encontrar algo que uniquify la variable temp:

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 
) 

Esto evitará enfrentamientos entre varios lotes de funcionamiento.Sin embargo, actualmente no está utilizando nada para bloquear la escritura en su archivo de registro y las cosas pueden aparecer fuera de lugar cuando se escriben otras cosas (con otros lotes puede intercalarse en los comandos echo y type o, cuando está redireccionando salida de java a ese archivo y, a continuación, puede ser confundida con la producción regular del programa 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 

puede utilizar otro archivo como semáforos para escribir en el registro para evitar las salidas de proceso por lotes que se mezclen: cree el archivo [copy nul file] cuando desee escribir en el registro, elimínelo posteriormente y antes de intentar crearlo, compruebe si realmente está allí y espere hasta que desaparezca. No puede hacer nada para que el registro stdout se mezcle en el sin embargo, excepto que utiliza ese enfoque de archivo temporal para stdout (y simplemente type el registro de stdout a log.txt cuando finalizó el programa Java, pero de nuevo con el uso del semáforo.

0

Un archivo por lotes como este debería ser el truco.

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 

Aquí estoy pasando stderr a través de una tubería y el paso de argumentos como argumentos. El resultado se agrega a un archivo log.txt.

Tirar stdout

1>nul 

stderr Redirigir a la salida estándar

2>&1 

Pipe el stderr en un guión para dar formato a la salida, y pasar argumentos como argumentos.

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

adjuntar la salida a un "log.txt".

>>log.txt 

En mi sistema necesito llamar a python.exe de lo contrario la tubería no funciona.

Éstos son los dos archivos que usé "something.py" y "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 

Y finaly Aquí está la salida.

registro.txt

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

Lo único que falta es que siempre hay algo que se escribe en el "log.txt" archivo .

Para arreglar esto más adelante me movería escribiendo el archivo de registro en "format_output.py".

Luego puede agregar un cheque para ver si el stderr de su programa está en blanco.

+0

A menos que esté realmente equivocado, la lógica falla * * 2> y 1 1> nul **. Envías todos y cada salida a NUL, sin tener nada saltando la tubería a Python. Lamentablemente no puedo probarlo, ¿verdad? – Jay

3

Algo como esto podría funcionar:

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 
) 

No soy un programador de Java a mí mismo, no puedo probar esta salida/situación, pero:

1:% * significa todos los parámetros, desde el 1 hasta el último (incluso% 12 aunque no está disponible directamente ...) cualquiera que sea el formato En g. Sería mejor usar esto que delimitar esos. En el caso de un espaciado/presupuesto incorrecto, también tendría los parámetros completos. Agregué una línea en el registro, para mostrar la línea completa y luego los parámetros. Puedes ver dónde estaba el problema si es una cuestión de malos argumentos.

2: enviar la salida estándar a nulo (^> nul) sólo se mantendrá la salida stderr, puesto en %% e

3: lo que está en la parte hacer sólo se suceder es el para declaración de prueba en realidad tiene algo como un resultado, es decir, si se establece %% e.

Dicho esto, debe probar el script y ver si la excepción se envía realmente a stderr o, como algunos otros softwares, a stdout incluso si se produce un error.

Espero que esto ayude.

Cuestiones relacionadas