32

デフォルトでは、バッチ ファイルは最後のコマンドのエラー コードを返します。

以前のコマンドのエラーコードを返すことは何とか可能ですか? 最も注目すべきは、パイプ内のコマンドのエラー コードを返すことは可能ですか?

たとえば、この 1 行のバッチ スクリプト

foo.exe

fooのエラーコードを返します。しかし、これは:

foo.exe | tee output.txt

常にゼロであるteeの終了コードを返します。

4

6 に答える 6

11

同様の問題があり、成功または失敗だけで正確なエラーコードを検出する必要がなかったため、次の解決策に落ち着きました。

echo > .failed.tmp    

( foo.exe && del .failed.tmp ) | tee foo.log

if exist .failed.tmp (
    del .failed.tmp
    exit /b 1
) else (
    exit /b 0
)
于 2014-10-05T21:05:37.830 に答える
2

%ERRORLEVEL%変数は、パイプコマンドが実行される前に更新されません。他の回答でアドバイスされているように、ラッパーを使用する必要があります。

ただし、「IF ERRORLEVEL#」は使用できます。例えば:

(
type filename
@REM Use an existing (or not) filename to test each branch
IF ERRORLEVEL 1 (echo ERROR) ELSE (echo OKAY)
) > logfile.txt

ECHOは、エラーが返された場合にのみ実行されます。ただし、%ERRORLEVEL%は一貫していないようです。

編集:サンプルをそのまま実行できるように変更しました。

于 2011-10-06T19:22:42.833 に答える
2

単一のコマンドではなく、エントリのバットファイルに対してティーを呼び出し、エラーレベルを自由に使用するには、次のようなトリックを使用します。

if "%1" == "body" goto :body
call %0 body | tee log.txt
goto :eof
:body

set nls_lang=american_america
set HomePath=%~dp0

sqlplus "usr/pwd@tnsname" "@%HomePath%script.sql" 
if errorlevel 1 goto dberror

rem Here I can do something which is dependent on correct finish of script.sql    

:dberror

echo script.sqlerror failed

これにより、tee の使用とバッチ内のコマンドの呼び出しが分離されます。

于 2016-12-28T14:18:28.863 に答える
2

約1日掘り下げた後、私はそれを行う方法を見つけました:

set error_=0
9>&1 1>&2 2>&9 (for /f "delims=" %%i in ('9^>^&1 1^>^&2 2^>^&9 ^(^(^(2^>^&1 call "%homeDir%%1"^) ^|^| ^(1^>^&2 2^>nul echo FAILED^)^) ^| 2^>nul "%homeDir%mtee" /T /+ "%homeDir%logs\%date_%_%1.log"^)') do (set error_=1))

exit /b %error_%

上記の例では、「%homeDir%%1」が実行されており、その出力は「%homeDir%mtee」にパイプされています。この行は失敗を検出します (バッチ コンテキストとその stdin/stdout/stderr 割り当ての図を描いて、その動作を理解することをお勧めします :-) )。実際のエラーレベルを抽出する良い方法が見つかりませんでした。私が得た最良のことは、「echo」コマンドを、次のようなバッチスクリプト呼び出し「call rc.bat」に置き換えることでした。

@echo %errorlevel%

次に、「set error_=1」を「set error_=%%i」に置き換えます。

しかし問題は、この呼び出しも失敗する可能性があり、それを検出するのは容易ではないということです。それでも、何もないよりはましです。インターネット上で解決策が見つかりませんでした。

于 2010-01-02T03:50:20.323 に答える
1

この問題は、コマンド ファイルのラッパーを作成することで解決できます。

rem wrapper for command file, wrapper.cmd

call foo.exe

echo %errorlevel%

if errorlevel 1 goto...

次に、tee をラッパーに追加します。

wrapper.cmd | tee result.log

もちろん、これはまったく同じではありません。たとえば、ラップされたファイルに複数のファイルをログインしたい場合、それは不可能ですが、私の場合は問題を解決しました。

于 2010-07-15T10:21:26.363 に答える