web-dev-qa-db-ja.com

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

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

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

148
APerson

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

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

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

パラメータが渡されたかどうかを確認する

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

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

9つ以上の引数にアクセスする必要がある場合は、SHIFTコマンドを使用する必要があります。このコマンドは、%0%1の値を取る、%1%2の値を取るなど、すべての引数の値を1桁シフトします。%9SHIFTを呼び出す前に変数を介して使用できなかった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 /?と入力すると、これらの機能の全範囲を表示できます。

276
Jon

バッチファイルでパラメータを使用する:%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
51
Eric Leschinski

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

Hello.batがあり、内容が

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

次のコマンドでバッチインコマンドを呼び出します。

hello.bat APerson241%date%

このメッセージを受け取るはずです。

こんにちは、APerson241このバッチファイルを実行してくれてありがとう(01/11/2013)

5
rud3y

変数、つまり.BAT変数を使用し、%0から%9と呼びます。

3
tohava

@ 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 で私の同じような投稿を参照してください。ここで私は論理で何が起こっているのか、そしてなぜ私は特定の構成要素を使ったのかについてもっと分析を提供します。

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

1
Garret Wilson