2009-05-28 7 views
10

J'ai un fichier batch qui exécute une application Java. J'essaie de le modifier afin que chaque fois qu'une exception se produit, il écrira le STDERR dans un fichier.Rediriger le lot stderr vers le fichier

Il ressemble à ceci:

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

Est-il possible que je peux écrire les arguments% 1 et 2% dans le fichier log.txt ainsi? Je ne veux pas l'écrire dans le fichier journal chaque fois que ce fichier de commandes est appelé, uniquement lorsqu'une exception se produit.

J'ai essayé de trouver un moyen de rediriger STDERR dans une variable, mais je n'ai pas pu le comprendre. Idéalement, je voudrais le fichier journal pour ressembler à quelque chose comme:

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

Répondre

0

Que diriez-vous quelque chose comme ça (non testé):

@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

Mais cela consignerait la sortie chaque fois que le fichier de commandes était appelé, n'est-ce pas? Je voudrais éviter cela si possible et juste l'enregistrer si l'application java lance une exception. – nivlam

2

Je ne comprends pas exactement ce que vous demandez, mais voici quelques info qui peut aider ...

Vous pouvez rediriger stderr séparément de stdout dans un fichier .cmd ou .bat. Pour rediriger stderr, utilisez quelque chose comme ceci:

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

Ensuite, vous pouvez vérifier la command.stderr.txt pour le contenu, et le cas échéant est présent, concaténer au command.stdout.txt dans votre fichier journal. Ou vous pouvez le concerter dans tous les cas. Si vous le souhaitez, vous pouvez également renvoyer la commande que vous avez exécutée dans le fichier journal final.

Vous pouvez également vérifier le code de sortie dans un fichier de commandes, en utilisant la variable% ERRORLEVEL% env. Les fichiers EXE doivent définir ERRORLEVEL en cas d'erreur. Je ne sais pas si java.exe fait cela. Il devrait, si c'est un bon citoyen sur Windows. Cela peut être un moyen alternatif de savoir si l'application Java est sortie avec une condition d'erreur. Mais ce n'est pas une garantie que stderr n'a rien. Par exemple, une application Java peut imprimer une exception et une trace de pile, puis quitter avec le code 0, ce qui indique la réussite. Dans ce cas, stderr aurait gunk dedans, mais ERRORLEVEL serait zéro.

EDIT: s/ERROR_LEVEL/ERRORLEVEL

+0

J'essaie d'éviter d'écrire dans un fichier chaque fois que ce fichier batch est appelé. Ce fichier batch est appelé très souvent et il vit sur un serveur déjà saturé d'E/S. – nivlam

+0

Mal interprété votre réponse un peu. J'écris déjà le fichier stderr dans un fichier journal, mais je veux aussi écrire les paramètres qui ont été transmis au fichier batch. Je veux seulement enregistrer ces paramètres quand il écrit stderr dans le journal. – nivlam

+0

Il s'appelle% ERRORLEVEL%, et non% ERROR_LEVEL%. En outre, vous devriez vérifier avec "if errorlevel 1 ..." ne pas comparer à% errorlevel% qui n'existe pas réellement. – Joey

0

Essayez d'utiliser 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

J'ai juste essayé ceci et errorlevel est toujours zéro, même quand java lance une exception. – nivlam

+0

Si la classe principale java est écrite par vous, vous pouvez envelopper tout le contenu dans un try/catch et utiliser exit (1) dans catch block pour définir le niveau d'erreur dans l'environnement –

2

La seule solution de travail que je vois serait de rediriger stderr vers un fichier temporaire

java blah.jar %1 %2 2>stderr 

et ensuite regarder si quelque chose a été écrit dans le fichier et écrire dans le journal dans ce cas.

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

Si les lots ne sont pas exécutés en séquence mais en même temps vous devez trouver quelque chose à 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 
) 

Cela évitera des affrontements entre plusieurs lots en cours d'exécution.Cependant, vous n'utilisez actuellement rien pour verrouiller l'écriture dans votre fichier journal et les éléments peuvent sembler hors de propos lorsque d'autres éléments sont écrits (avec d'autres lots, vous pouvez obtenir l'entrelacement dans les commandes echo et type ou, lorsque vous redirigez sortie de java à ce fichier aussi bien, alors il peut se mélanger avec la sortie régulière du programme 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 

Vous pouvez utiliser un autre fichier comme sémaphores pour écrire dans le journal pour éviter les sorties de lots traînes: créez le fichier [copy nul file] lorsque vous voulez écrire dans le journal, supprimez-le par la suite et avant de tenter de le créer, vérifiez s'il existe réellement et attendez qu'il disparaisse.Vous ne pouvez rien faire pour que le journal stdout soit mélangé la fichier, cependant, sauf que vous utilisez cette approche de fichier temporaire pour stdout ainsi (et simplement type le journal stdout à log.txt lorsque le programme Java a fini, mais, encore une fois avec l'aide du sémaphore.

0

Un fichier séquentiel comme celui-ci devrait faire l'affaire.

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 

Ici je passe stderr par un tuyau et passer des arguments comme arguments. La sortie est ensuite ajoutée à un fichier log.txt.

Jeter stdout

1>nul 

Rediriger stderr à stdout

2>&1 

pipe stderr dans un script pour formater la sortie, et transmettre des arguments comme arguments.

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

Append sortie à un "log.txt".

>>log.txt 

Sur mon système, j'ai besoin d'appeler python.exe sinon le tuyau ne fonctionne pas.

Voici les deux fichiers que j'ai utilisé "something.py" et "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 

Et la sortie est ici finaly.

log.txt

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

La seule chose qui manque est que quelque chose est toujours écrit à la "log.txt" fichier.

Pour ranger cela plus loin, je voudrais déplacer le fichier journal dans "format_output.py".

Vous pouvez ensuite ajouter une vérification pour voir si le stderr de votre programme est vide.

+0

À moins que je ne me trompe vraiment, la logique échoue avec * * 2> & 1 1> nul **. Vous envoyez tout et n'importe quelle sortie à NUL, n'ayant ainsi rien qui saute le tuyau à python. Je ne peux malheureusement pas le tester, n'est-ce pas? – Jay

3

Quelque chose comme cela pourrait fonctionner:

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 
) 

Je ne suis pas un programmeur java moi-même, je ne peux pas tester cette sortie/situation, mais:

1:% * signifie tous les paramètres, du 1er au dernier (même% 12 bien qu'il ne soit pas directement disponible ..) quel que soit le format ing. Peut-être vaut-il mieux utiliser cela que de les délimiter. Dans le cas de mauvais espacement/devis, vous auriez les paramètres complets aussi. J'ai ajouté une ligne dans le journal, pour montrer la ligne complète puis les paramètres. Vous pouvez voir où se situe le problème s'il s'agit de mauvais arguments.

2: l'envoi de la sortie standard null (^> nul) ne peut conserver la sortie stderr, mis en %% e

3: Quelle que soit la faire partie ne fera que arrive est le pour test a réellement quelque chose comme une sortie, c'est à dire si %% e est réglé. Cela dit, vous devez tester le script et voir si l'exception est réellement envoyée à stderr ou, comme d'autres logiciels, à stdout même si une erreur est survenue.

J'espère que cela aide.