Windowsでは、バッチファイルの実行時に渡される引数にどのようにアクセスしますか?
たとえば、という名前のプログラムがあるとしhello.bat
ます。hello -a
Windowsコマンドラインで入力するときに-a
、引数として渡されたことをプログラムにどのように通知しますか?
Windowsでは、バッチファイルの実行時に渡される引数にどのようにアクセスしますか?
たとえば、という名前のプログラムがあるとしhello.bat
ます。hello -a
Windowsコマンドラインで入力するときに-a
、引数として渡されたことをプログラムにどのように通知しますか?
回答:
他の人がすでに述べたように、コマンドラインを介して渡されたパラメータは、表記%1
がのバッチファイルでアクセスできます%9
。使用できる他の2つのトークンもあります。
%0
で、コマンドラインで指定された実行可能ファイル(バッチファイル)の名前が。%*
で、コマンドラインで指定されたすべてのパラメータ -あなたが別のプログラムにパラメータを転送する場合、これは非常に便利です。パラメータにアクセスする方法に加えて、知っておくべき重要なテクニックがたくさんあります。
これはのような構成で行われます。これはIF "%~1"==""
、引数がまったく渡されなかった場合にのみ当てはまります。チルダ文字に注意してください。これにより、周囲の引用符がの値から削除されます%1
。チルダがないと、構文エラーの可能性を含め、その値に二重引用符が含まれていると、予期しない結果になります。
9つ以上の引数にアクセスする必要がある場合は、コマンドを使用する必要がありますSHIFT
。このコマンドは、すべての引数の値が1位をシフトし、そのためには%0
の値をとる%1
、%1
の値をとる%2
、など%9
を呼び出す前に、すべての変数を介して利用できなかった第十引数(存在する場合)の値をとるSHIFT
(入力してください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 /?
コマンドプロンプトに入力すると、これらの機能の全範囲を表示できます。
"name=John"
は、実行name John
中になります。回避策は、単一引用符で囲むことです'"name=John"'
CALL /?
!?ここで私はずっとGoogleとぶつかっています。
バッチファイルでのパラメーターの使用:%0および%9
バッチファイルは、tokens:%0
toでパラメーターとして渡された単語を参照できます%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
は呼び出されたときのプログラム名なので%0
、ブート時に起動すると、DOS ではAUTOEXEC.BATは空になります。
例:
次のコマンドをと呼ばれるバッチファイルに入れますmybatch.bat
。
@echo off
@echo hello %1 %2
pause
次のようにバッチファイルを呼び出すと、次のようにmybatch john billy
出力されます。
hello john billy
バッチファイルの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、このバッチファイルを実行していただきありがとうございます(2013年11月11日)
@ジョンの :parse
/ :endparse
スキームは素晴らしいスタートであり、彼は最初のパスに感謝しますが、Windowsの拷問バッチシステムで簡単にそれができると思うなら、まあ、私の友人、あなたはショックを受けています。私はこの悪魔と一緒に一日中過ごしました、そして多くの苦しい研究と実験の後、私はようやく実際のユーティリティに実行可能な何かを管理しました。
ユーティリティを実装したいとしましょうfoobar
。初期コマンドが必要です。これはオプションのパラメータ有する--foo
かかるオプション(もちろん、他のパラメータとすることができません)の値を、値がない場合、デフォルトでになりdefault
ます。また--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で参照してください。ロジックで何が起こっているか、および特定の構造を使用した理由を詳しく分析しています。
恐ろしいです。そのほとんどは今日学ばなければなりませんでした。そしてそれは痛い。