2009-05-28 16 views
10

Ho un file batch che esegue un'applicazione java. Sto provando a modificarlo in modo che ogni volta che si verifica un'eccezione, scriverà STDERR su un file.Reindirizza batch stderr su file

Sembra qualcosa di simile a questo:

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

C'è un modo posso scrivere l'argomento% 1 e 2% al file log.txt come bene? Non voglio scriverlo nel file di registro ogni volta che viene chiamato questo file batch, solo quando si verifica un'eccezione.

Ho provato a cercare un modo per reindirizzare lo STDERR in una variabile, ma non riuscivo a capirlo. Idealmente mi piacerebbe il file di registro per un aspetto simile:

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

risposta

0

Che ne dite di qualcosa di simile (non testata):

@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

Ma questo registra l'output ogni volta che viene chiamato il file batch, vero? Vorrei evitarlo e, se possibile, registrarlo solo se l'app java genera un'eccezione. – nivlam

2

non capisco esattamente quello che stai chiedendo, ma qui è un po ' informazioni che possono essere d'aiuto ...

È possibile reindirizzare lo stderr separatamente dallo stdout in un file .cmd o .bat. Per reindirizzare stderr, usare qualcosa di simile a questo:

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

Quindi, è possibile controllare il command.stderr.txt per i contenuti, e se qualcuno è presente, concatenare al command.stdout.txt nel file di registro. O potresti concatenarlo in ogni caso. Se vuoi, puoi anche echo il comando che hai eseguito, nel file di registro finale.

È anche possibile verificare il codice di uscita in un file batch, utilizzando% ERRORLEVEL% env var. Ci si aspetta che i file exe impostino ERRORLEVEL in caso di errore. Non so se java.exe faccia questo. Dovrebbe, se è un buon cittadino su Windows. Questo potrebbe essere un modo alternativo per scoprire se l'app Java è stata chiusa con una condizione di errore. Ma questo non garantisce che stderr non abbia ottenuto nulla. Ad esempio, un'app Java potrebbe stampare un'eccezione e una traccia di stack, quindi uscire con il codice 0, che indica il successo. Nel qual caso stderr avrebbe gunk in esso, ma ERRORLEVEL sarebbe zero.

EDIT: s/ERROR_LEVEL/ERRORLEVEL

+0

Sto cercando di evitare di scrivere su un file ogni volta che viene chiamato questo file batch. Questo file batch viene chiamato molto spesso e vive su un server già saturo di IO. – nivlam

+0

Scambia un po 'la tua risposta. Sto già scrivendo lo stderr su un file di log, ma voglio provare a scrivere anche i parametri che sono stati passati al file batch. Voglio solo registrare questi parametri quando scrive stderr nel log. – nivlam

+0

Si chiama% ERRORLEVEL%, non% ERROR_LEVEL%. Inoltre dovresti controllarlo con "if errorlevel 1 ..." che non si confronta con% errorlevel% che in realtà non esiste. – Joey

0

Prova utilizzando 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

Ho appena provato questo e errorlevel è sempre zero, anche quando java lancia un'eccezione. – nivlam

+0

Se la classe principale Java è scritto da voi, si può avvolgere tutta la roba in un try/catch e utilizzare l'uscita (1) nel blocco catch per impostare il livello di errore in ambiente –

2

L'unica soluzione di lavoro che vedo sarebbe quello di reindirizzare stderr in un file temporaneo

java blah.jar %1 %2 2>stderr 

e in seguito verificare se qualcosa è stato scritto sul file e scrivere sul registro in quel caso.

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

Se le partite non vengono eseguite in sequenza, ma piuttosto allo stesso tempo è necessario trovare qualcosa da uniquify la variabile 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 
) 

Questo permetterà di evitare gli scontri tra più batch in esecuzione.Tuttavia, al momento non stai utilizzando nulla per bloccare la scrittura sul tuo file di log e le cose potrebbero apparire fuori luogo quando altre cose vengono scritte su di esso (con altri lotti potresti ottenere interleaving nei comandi echo e type o, quando stai reindirizzando uscita di java a quel file così, allora può confondersi con l'uscita regolare del programma 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 

è possibile utilizzare un altro file come un semaforo per iscritto al registro per evitare le uscite lotti confondersi: crea il file [copy nul file] quando vuoi scrivere nel registro, cancellalo in seguito e prima di tentare di crearlo controlla se è effettivamente lì e aspetta fino a quando non scompare. Non puoi fare nulla sul log di stdout il file, tuttavia, eccetto che si utilizza l'approccio temp file per lo stdout (e semplicemente type il log stdout su log.txt quando il programma Java è terminato, ma, ancora usando il semaforo.

0

Un file batch come questo dovrebbe fare il trucco.

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 

Qui sto passando stderr attraverso un tubo e il passaggio di argomenti come argomenti. L'output viene quindi aggiunto a un file log.txt.

Gettare via stdout

1>nul 

reindirizzamento errore a stdout

2>&1 

tubo stderr in uno script per formattare l'output, e passare argomenti come argomenti.

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

uscita aggiungere a un "log.txt".

>>log.txt 

Sul mio sistema ho bisogno di chiamare python.exe altrimenti la pipe non funziona.

Qui ci sono i due file che ho usato "something.py" e "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 

E finalmente ecco l'output.

log.txt

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

L'unica cosa che manca è che qualcosa è sempre scritto per il file di"log.txt".

Per sistemare ulteriormente, spostarei il file di registro in "format_output.py".

Si potrebbe quindi aggiungere un controllo per vedere se lo stderr dal programma è vuota.

+0

A meno che io sono davvero sbagliato, la logica non riesce con * * 2> & 1 1> nul **. Mandate tutto e tutti gli output a NUL, quindi non avete nulla che salta la pipa a Python. Purtroppo non posso testarlo, vero? – Jay

3

Qualcosa di simile potrebbe funzionare:

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 
) 

io non sono un programmatore java me stesso, non posso verificare questa uscita/situazione, ma:

1:% * indica ogni parametro, dal primo all'ultimo (anche% 12 anche se non è direttamente disponibile ..) indipendentemente dal formato ing. Potrebbe essere meglio usare questo che delimitarli. In caso di spaziatura/quotazione errata, si avranno anche i parametri completi. Ho aggiunto una riga nel registro, per mostrare l'intera riga, quindi i parametri. Puoi vedere dove si trovava il problema se si tratta di argomenti errati.

2: l'invio del stdout su null (^> nul) manterrà solo l'uscita stderr, incastonato nella %% e

3: Qualunque sia nella fare parte solo la volontà accadere è il per dichiarazione test ha in realtà nulla come uscita, vale a dire se %% e è impostato.

Con ciò detto, è necessario testare lo script e verificare se l'eccezione è effettivamente inviata a stderr o, come altri software, allo stdout anche se si è verificato un errore.

Spero che questo aiuti.