2009-05-28 29 views
10

Tôi có một tệp lô thực hiện một ứng dụng java. Tôi đang cố gắng sửa đổi nó để bất cứ khi nào một ngoại lệ xảy ra, nó sẽ viết STDERR ra một tập tin.Chuyển hướng hàng loạt stderr vào tập tin

Nó trông giống như sau:

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

Có cách nào tôi có thể viết các đối số% 1 và% 2 đến tập tin log.txt không? Tôi không muốn viết nó vào file bản ghi mỗi khi tập tin batch này được gọi, chỉ khi một ngoại lệ xảy ra.

Tôi đã thử tìm cách chuyển hướng STDERR thành biến, nhưng tôi không thể tìm ra. Lý tưởng nhất là tôi muốn các log file để tìm kiếm một cái gì đó như:

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

Trả lời

0

Làm thế nào về một cái gì đó như thế này (chưa được kiểm tra):

@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

Nhưng điều đó sẽ ghi lại đầu ra mỗi lần tệp lô được gọi là không? Tôi muốn tránh rằng nếu có thể và chỉ cần có nó đăng nhập nếu ứng dụng java ném một ngoại lệ. – nivlam

2

Tôi không nhận được chính xác những gì bạn đang yêu cầu, nhưng đây là một số thông tin có thể giúp ...

Bạn có thể chuyển hướng stderr riêng biệt từ stdout trong tệp .cmd hoặc .bat. Để chuyển hướng stderr, sử dụng một cái gì đó như thế này:

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

Sau đó, bạn có thể kiểm tra command.stderr.txt cho nội dung, và nếu có là hiện tại, nối nó vào command.stdout.txt vào log file của bạn. Hoặc bạn có thể concat nó trong mọi trường hợp. Nếu bạn thích bạn cũng có thể lặp lại lệnh mà bạn đã chạy, vào tệp nhật ký cuối cùng.

Bạn cũng có thể kiểm tra mã thoát trong tệp lô, sử dụng% ERRORLEVEL% env var. Các tệp exe được dự kiến ​​sẽ đặt ERRORLEVEL trong trường hợp có lỗi. Tôi không biết nếu java.exe thực hiện điều này. Nó nên, nếu nó là một công dân tốt trên Windows. Đây có thể là một cách thay thế để tìm hiểu xem ứng dụng Java có bị lỗi hay không. Nhưng điều này không đảm bảo rằng stderr không có gì. Ví dụ, một ứng dụng Java có thể in ra một ngoại lệ và theo dõi ngăn xếp, và sau đó thoát ra với mã 0, cho biết thành công. Trong trường hợp đó, stderr sẽ có gunk trong đó, nhưng ERRORLEVEL sẽ bằng không.

EDIT: s/ERROR_LEVEL/ERRORLEVEL

+0

Tôi đang cố gắng tránh ghi vào một tập tin mỗi khi tập tin thực thi này được gọi. Tập tin batch này được gọi rất thường xuyên và nó tồn tại trên một máy chủ đã bão hòa đã được IO. – nivlam

+0

Đọc sai câu trả lời của bạn một chút. Tôi đã viết stderr ra một tập tin đăng nhập, nhưng tôi muốn thử và viết ra các tham số đã được chuyển đến tập tin thực thi. Tôi chỉ muốn đăng nhập các tham số này khi nó ghi stderr vào nhật ký. – nivlam

+0

Nó được gọi là% ERRORLEVEL%, không phải% ERROR_LEVEL%. Hơn nữa, bạn nên kiểm tra nó với "nếu errorlevel 1 ..." không so sánh với% errorlevel% mà không thực sự tồn tại. – Joey

0

Hãy thử sử dụng 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

Tôi chỉ cố gắng này và errorlevel luôn luôn là số không, ngay cả khi java ném một ngoại lệ. – nivlam

+0

Nếu lớp chính java được viết bởi bạn, bạn có thể bọc toàn bộ nội dung trong try/catch và sử dụng thoát (1) trong khối catch để đặt mức lỗi trong môi trường –

2

Giải pháp duy nhất làm việc tôi thấy sẽ được chuyển hướng stderr vào một tập tin tạm thời

java blah.jar %1 %2 2>stderr 

và sau đó tìm kiếm một cái gì đó đã được ghi vào tập tin và ghi vào nhật ký trong trường hợp đó.

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

Nếu lô không chạy theo thứ tự mà là cùng một lúc bạn cần phải tìm cái gì đó để uniquify các biến 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 
) 

Điều này sẽ tránh đụng độ giữa nhiều lô chạy.Tuy nhiên, bạn hiện không sử dụng bất kỳ thứ gì để khóa văn bản vào tệp nhật ký của mình và mọi thứ có thể xuất hiện ngoài chỗ khi những thứ khác được ghi vào đó (với các lô khác bạn có thể xen kẽ trong các lệnh echotype hoặc khi bạn đang chuyển hướng đầu ra của java để tập tin đó là tốt, sau đó nó có thể bị lẫn lộn với sản lượng thường xuyên của chương trình 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 

Bạn có thể sử dụng một tập tin như semaphore để viết vào nhật ký để tránh những kết quả đầu ra hàng loạt nhận được hỗn hợp: tạo ra các tập tin [copy nul file] khi bạn muốn ghi vào nhật ký, xóa nó sau đó và trước khi bạn cố gắng tạo nó kiểm tra xem nó có thực sự ở đó và chờ cho đến khi nó biến mất không. Bạn không thể làm bất cứ điều gì về bản ghi stdout được trộn vào các tuy nhiên, ngoại trừ bạn sử dụng phương pháp tiếp cận tệp tạm thời đó cho stdout (và chỉ cần type nhật ký stdout để log.txt khi chương trình Java kết thúc, nhưng, một lần nữa bằng cách sử dụng semaphore.

0

Một tệp hàng loạt như thế này sẽ thực hiện thủ thuật.

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 

Ở đây tôi đang đi qua stderr thông qua một đường ống và qua các đối số như các đối số. Đầu ra sau đó được nối thêm vào tệp log.txt.

Ném đi stdout

1>nul 

Redirect stderr stdout

2>&1 

ống stderr vào một kịch bản để định dạng đầu ra, và vượt qua đối số như các đối số.

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

Thêm đầu ra vào "log.txt".

>>log.txt 

Trên hệ thống của tôi, tôi cần gọi python.exe nếu không đường ống không hoạt động.

Dưới đây là hai tệp tôi đã sử dụng "something.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 

và cuối cùng đây là đầu ra.

log.txt

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

Điều duy nhất còn thiếu là một cái gì đó luôn luôn ghi vào "log.txt" tập tin .

Để gọn gàng hơn nữa, tôi sẽ di chuyển ghi tệp nhật ký vào "format_output.py".

Sau đó, bạn có thể thêm một dấu kiểm để xem liệu trình chuẩn bị từ chương trình của bạn có trống hay không.

+0

Trừ khi tôi thực sự nhầm lẫn, logic không thành công với * * 2> & 1 1> nul **. Bạn gửi tất cả và bất kỳ đầu ra để NUL, do đó không có bất cứ điều gì nhảy ống để python. Tôi buồn bã không thể kiểm tra nó, phải không? – Jay

3

Something như thế này có thể làm việc:

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 
) 

Tôi không phải là một java lập trình bản thân mình, tôi không thể kiểm tra đầu ra này/tình hình nhưng:

1:% * có nghĩa là mọi thông số, từ 1 đến cuối (thậm chí% 12 mặc dù không có sẵn trực tiếp ..) bất kể định dạng nào ing. Có thể là tốt hơn để sử dụng này hơn delimit những người. Ngay cả khoảng cách/trích dẫn không tốt, bạn cũng sẽ có đầy đủ thông số. Tôi đã thêm một dòng trong nhật ký, để hiển thị toàn bộ dòng rồi tham số. Bạn có thể thấy nơi mà vấn đề là nếu đó là vấn đề của các đối số xấu.

2: gửi stdout null (^> nul) sẽ chỉ giữ cho đầu ra stderr, đặt vào %% e

3: Dù là trong làm phần sẽ chỉ xảy ra là cho câu hỏi kiểm tra thực sự có bất kỳ thứ gì là đầu ra, tức là nếu %% e được đặt.

Với những người đang nói, bạn phải kiểm tra tập lệnh và xem liệu ngoại lệ có thực sự được gửi tới stderr hay không, giống như một số phần mềm khác, để stdout ngay cả khi đã xảy ra lỗi.

Tôi hy vọng điều này sẽ hữu ích.

Các vấn đề liên quan