Windowsコマンドラインでバッチファイルのパラメーターを使用する


161

Windowsでは、バッチファイルの実行時に渡される引数にどのようにアクセスしますか?

たとえば、という名前のプログラムがあるとしhello.batます。hello -aWindowsコマンドラインで入力するときに-a、引数として渡されたことをプログラムにどのように通知しますか?


:バッチファイルにコマンドラインパラメータを渡す方法stackoverflow.com/questions/26551/...
エリックLeschinski

3
彼は「DOSコマンドライン」について言及しています。
David R Tribble 2013年

回答:


287

他の人がすでに述べたように、コマンドラインを介して渡されたパラメータは、表記%1がのバッチファイルでアクセスできます%9。使用できる他の2つのトークンもあります。

  • %0、コマンドラインで指定された実行可能ファイル(バッチファイル)の名前が
  • %*、コマンドラインで指定されたすべてのパラメータ -あなたが別のプログラムにパラメータを転送する場合、これは非常に便利です。

パラメータにアクセスする方法に加えて、知っておくべき重要なテクニックがたくさんあります。

パラメータが渡されたかどうかの確認

これはのような構成で行われます。これはIF "%~1"==""、引数がまったく渡されなかった場合にのみ当てはまります。チルダ文字に注意してください。これにより、周囲の引用符がの値から削除されます%1。チルダがないと、構文エラーの可能性を含め、その値に二重引用符が含まれていると、予期しない結果になります。

9つ以上の引数を処理する(または単に人生を楽にする)

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 /?コマンドプロンプトに入力すると、これらの機能の全範囲を表示できます。


4
:parse、:endparseコンストラクトは、GOTOを使用しても美しさがあります。ありがとう!(つまり、DOS-BASIC強制GOTO)
mmrtnt 2013

1
このテクニックは、PowershellからBATを呼び出すときに失敗する場合があります。のような引用された引数"name=John"は、実行name John中になります。回避策は、単一引用符で囲むことです'"name=John"'
cmcginty

1
どのようにして私はなしでそんなに長く行ってきましたCALL /?!?ここで私はずっとGoogleとぶつかっています。
bigtlb 2018年

@ジョン私はコマンドを介してそれを呼び出す場合、1つのコードエコー%1のみを含むbatファイルを作成しました。例:xx.bat&parameter> "C:\ yy.txt"パラメータ付きのbatファイルを呼び出し、txtファイルに書き込みますが、最初または最後のパラメータで機能していません。その他のテキストは問題なく機能します。
Alex Mathew

56

バッチファイルでのパラメーターの使用:%0および%9

バッチファイルは、tokens:%0toでパラメーターとして渡された単語を参照できます%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

5

バッチファイルは、割り当てる変数である限り、プログラムの後にテキストを自動的に渡します。送信された順に渡されます。たとえば、%1はプログラムが呼び出された後に送信される最初の文字列になります。

Hello.batがあり、内容が次の場合:

@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause

そして、あなたはコマンドでバッチを呼び出す

hello.bat APerson241%date%

このメッセージが返されるはずです。

こんにちは、APerson241、このバッチファイルを実行していただきありがとうございます(2013年11月11日)


4

@ジョンの :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で参照してください。ロジックで何が起こっているか、および特定の構造を使用した理由を詳しく分析しています。

恐ろしいです。そのほとんどは今日学ばなければなりませんでした。そしてそれは痛い。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.