Windowsでは、バッチファイルの実行時に渡された引数にどのようにアクセスしますか?
たとえば、hello.bat
という名前のプログラムがあるとしましょう。 Windowsのコマンドラインでhello -a
を入力したとき、-a
が引数として渡されたことをプログラムに知らせるにはどうすればよいですか。
他の人がすでに述べたように、コマンドラインを介して渡されるパラメーターは、%1
から%9
の表記を使用してバッチファイルでアクセスできます。使用できる他の2つのトークンもあります。
%0
はコマンドラインで指定された実行可能(バッチファイル)名です。%*
はコマンドラインで指定されたすべてのパラメーター-パラメーターを別のプログラムに転送する場合に非常に便利です。パラメータにアクセスする方法だけでなく、知っておくべき重要なテクニックもたくさんあります。
これは、IF "%~1"==""
のような構造で行われます。これは、引数がまったく渡されなかった場合にのみtrueです。 %1
の値から周囲の引用符が削除されるチルダ文字に注意してください。チルダがないと、その値に二重引用符が含まれている場合、構文エラーの可能性など、予期しない結果が得られます.
9つ以上の引数にアクセスする必要がある場合は、SHIFT
コマンドを使用する必要があります。このコマンドは、%0
が%1
の値を取る、%1
が%2
の値を取るなど、すべての引数の値を1桁シフトします。%9
SHIFT
を呼び出す前に変数を介して使用できなかった10番目の引数(存在する場合)の値を取ります(他のオプションについてはSHIFT /?
コマンドを入力します)。
SHIFT
は、特定の順序でパラメーターを提示する必要なく、パラメーターを簡単に処理する場合にも役立ちます。たとえば、スクリプトはフラグ-a
および-b
を任意の順序で認識できます。そのような場合にコマンドラインを解析する良い方法は
:parse
IF "%~1"=="" GOTO endparse
IF "%~1"=="-a" REM do something
IF "%~1"=="-b" REM do something else
SHIFT
GOTO parse
:endparse
REM ready for action!
このスキームにより、非常に複雑になることなく、非常に複雑なコマンドラインを解析できます。
ファイル名を表すパラメーターの場合、シェルは、他の方法ではアクセスできないファイルの操作に関連する多くの機能を提供します。この機能には、%~
で始まる構造体を使用してアクセスします。
たとえば、引数として渡されたファイルのサイズを取得するには
ECHO %~z1
バッチファイルが起動されたディレクトリのパスを取得するには(非常に便利です!)
ECHO %~dp0
コマンドプロンプトでCALL /?
と入力すると、これらの機能の全範囲を表示できます。
バッチファイルでパラメータを使用する:%0と%9
バッチファイルは、トークンでパラメータとして渡された単語を参照することができます:%0
から%9
。
%0 is the program name as it was called.
%1 is the first command line parameter
%2 is the second command line parameter
and so on till %9.
コマンドラインで渡されるパラメータは、英数字でスペースで区切る必要があります。 %0
は呼び出されたときのプログラム名なので、DOSでは、ブート時に%0
を起動すると、AUTOEXEC.BATのために空になります。
例:
次のコマンドをmybatch.bat
というバッチファイルに入れます。
@echo off
@echo hello %1 %2
pause
このようにバッチファイルを呼び出すと、mybatch john billy
が出力されます。
hello john billy
1つのバッチファイルに9個以上のパラメータを取得します。%* を使用してください。
パーセントスタートークン%*
は、「残りのパラメータ」を意味します。ここで定義されているように、forループを使ってそれらを取得することができます。
http://www.robvanderwoude.com/parameters.php
バッチパラメータの区切り文字に関する注意事項
コマンドラインパラメータの一部の文字は、DOSのバージョン、「エスケープ」されているかどうか、およびコマンドライン内の位置に応じて、バッチファイルで無視されます。
commas (",") are replaced by spaces, unless they are part of a string in
double quotes
semicolons (";") are replaced by spaces, unless they are part of a string in
double quotes
"=" characters are sometimes replaced by spaces, not if they are part of a
string in double quotes
the first forward slash ("/") is replaced by a space only if it immediately
follows the command, without a leading space
multiple spaces are replaced by a single space, unless they are part of a
string in double quotes
tabs are replaced by a single space
leading spaces before the first command line argument are ignored
それらを割り当てる変数である限り、バッチファイルは自動的にプログラムの後にテキストを渡します。それらは送信された順に渡されます。例えば%1は、プログラムが呼び出された後などに送信される最初の文字列になります。
Hello.batがあり、内容が
@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause
次のコマンドでバッチインコマンドを呼び出します。
hello.bat APerson241%date%
このメッセージを受け取るはずです。
こんにちは、APerson241このバッチファイルを実行してくれてありがとう(01/11/2013)
変数、つまり.BAT
変数を使用し、%0
から%9
と呼びます。
@ Jonの:parse
/:endparse
スキームは素晴らしいスタートです、そして彼が最初のパスに感謝しています、しかしあなたがWindowsの拷問のバッチシステムがそれを簡単にさせてくれると思うなら…あなたはショックを受けます。私は一日中この悪魔と一緒に過ごしました、そして多くの痛みを伴う研究と実験の後に私はついに現実の実用性のために実行可能な何かを管理しました。
ユーティリティfoobar
を実装したいとしましょう。初期コマンドが必要です。それは optional 値を取るオプションのパラメータ--foo
を持っています(もちろん他のパラメータにはなり得ません)。値が欠落している場合、デフォルトはdefault
です。また、 required の値をとるオプションのパラメータ--bar
もあります。最後に、値なしでフラグ--baz
を取ることができます。ああ、そしてこれらのパラメータは任意の順序で来ることができます。
つまり、このようになります。
foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]
複雑ですか?いいえ、それは現実の公益事業のかなり典型的なようです。 (git
だれか?)
さらに苦労することなく、これが解決策です。
@ECHO OFF
SETLOCAL
REM FooBar parameter demo
REM By Garret Wilson
SET CMD=%~1
IF "%CMD%" == "" (
GOTO usage
)
SET FOO=
SET DEFAULT_FOO=default
SET BAR=
SET BAZ=
SHIFT
:args
SET PARAM=%~1
SET ARG=%~2
IF "%PARAM%" == "--foo" (
SHIFT
IF NOT "%ARG%" == "" (
IF NOT "%ARG:~0,2%" == "--" (
SET FOO=%ARG%
SHIFT
) ELSE (
SET FOO=%DEFAULT_FOO%
)
) ELSE (
SET FOO=%DEFAULT_FOO%
)
) ELSE IF "%PARAM%" == "--bar" (
SHIFT
IF NOT "%ARG%" == "" (
SET BAR=%ARG%
SHIFT
) ELSE (
ECHO Missing bar value. 1>&2
ECHO:
GOTO usage
)
) ELSE IF "%PARAM%" == "--baz" (
SHIFT
SET BAZ=true
) ELSE IF "%PARAM%" == "" (
GOTO endargs
) ELSE (
ECHO Unrecognized option %1. 1>&2
ECHO:
GOTO usage
)
GOTO args
:endargs
ECHO Command: %CMD%
IF NOT "%FOO%" == "" (
ECHO Foo: %FOO%
)
IF NOT "%BAR%" == "" (
ECHO Bar: %BAR%
)
IF "%BAZ%" == "true" (
ECHO Baz
)
REM TODO do something with FOO, BAR, and/or BAZ
GOTO :eof
:usage
ECHO FooBar
ECHO Usage: foobar ^<command^> [--foo [^<fooval^>]] [--bar ^<barval^>] [--baz]
EXIT /B 1
はい、それは本当に悪いことです。 https://stackoverflow.com/a/50653047/421049 で私の同じような投稿を参照してください。ここで私は論理で何が起こっているのか、そしてなぜ私は特定の構成要素を使ったのかについてもっと分析を提供します。
恐ろしいです。そのほとんどは今日学ばなければなりませんでした。そしてそれは痛い。