質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

解決済

1回答

240閲覧

バッチから外部コマンドを呼んだ際に、文字列の戻り値とerrorlevelを同時に取得したい

AkiOsawa

総合スコア9

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

1クリップ

投稿2024/10/12 14:10

編集2024/10/12 17:35

外部コマンドが文字列を1つ返すものだった場合、例えばPythonだと、
for /f "delims=" %%A in ('python test.py') do set result=%%A
とか書けば戻り値は取れますが、直後のerrorlevelはfor文に対してなのでpythonでエラーが有っても1を返しません。

pythonでエラーがあったときにはバッチからリトライさせて、戻り値を取りたいのですが、どうすればよいでしょうか?

python側でprint(戻り値)を処理の最後に書いて、それ以前でエラーが起きていたら何も帰ってこない、か、戻り値はファイル渡し、というのは思いつくのですが、変な縛りになるし、できればバッチ側だけで処理したいと思っています。よろしくお願いします。

追記:
Copilot君も「戻り値をファイル渡しにするしか無理じゃね?」と言っているのでそうなのかもしれませんが、そうなるとtmpファイル名の重複を避けるために命名規則を決めなきゃならず、守っていないコードを見つけ出すのがとても難儀なのです。。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

出力をファイルに書くのが簡明です。一時ファイル名は、%0%RANDOM%%TIME%とかで、どうにかする。あるいは、mkdirを使って占有するディレクトリーを作ってその中に書くか。

副作用の無いプログラムだと、出力取得と、戻り値取得で、2回実行するのも分かり易いです。実行時間がそんなに長くなければですが。

それらが難しそうなら、他の手段はあります。
本来の出力の後で、戻り値を出力して、取得してから分ける。
お書きのコードからして、出力は必ず1行限定のようなので、その場合はわりと分かり易いです。
(ダブルクォートとシングルクォートを両方使うのでusebackqでバッククォートも使う)

CMD

1setlocal enabledelayedexpansion 2for /f "usebackq delims=" %%A in ( 3 `python -c "import os;print(os.system('python test.py'))"` 4 ) do set RESULT=!CC!&set CC=%%A 5echo OUTPUT=%RESULT% CC=%CC%

出力が複数行あるなら少し変えないと。

参考:占有のディレクトリーを作る

CMD

1setlocal 2set WORK_DIR=~~~~ 3:LOOP 4set MY_WORK=%WORK_DIR%\%~n0-%RANDOM% 5rem すでに別に処理で同名の物が作られていれば失敗するので別の名前でやり直す 6mkdir %MY_WORK% 2>NUL 7if ERRORLEVEL 1 goto LOOP 8 9python test.py >%MY_WORK%\foo.txt 10set CC=%ERRORLEVEL% 11type %MY_WORK%\foo.txt 12 13rmdir /s /q %MY_WORK%

追記:最初の案で遅延環境変数展開を使わずサブルーチンを使う

CMD

1setlocal 2for /f "usebackq delims=" %%A in ( 3 `python -c "import os;print(os.system('python test.py'))"` 4 ) do call :SUB "%%~A" 5echo OUTPUT=%RESULT% CC=%CC% 6exit /b 7 8:SUB 9set "RESULT=%CC%" 10set "CC=%~1" 11exit /b

投稿2024/10/13 00:39

編集2024/10/13 13:15
otn

総合スコア85766

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

AkiOsawa

2024/10/13 10:02

今まで遅延嫌いでしたが、こんな使い方があるとは、目からウロコです。大規模開発になればなるほどファイル渡しは使いたくないので、こちらを極めようと思います。ありがとうございました!
otn

2024/10/13 13:28 編集

変数を順繰りにずらせば良いだけなので、遅延環境変数展開を使わなくてもその部分をサブルーチンにすれば出来ます。追記しました。 > 今まで遅延嫌いでしたが ほとんどの場合は、サブルーチンにすることで、遅延環境変数展開は不要です。 変数値を引数で渡す時に、CMDの特殊記号がいろいろ含まれていると面倒or不可能ですが。 > 大規模開発になればなるほどファイル渡しは使いたくないので ストレージ経由を避けるとしたら速度要因くらいですが、速度を気にするなら、バッチファイルで良いのか?という気もします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問