web-dev-qa-db-ja.com

「.bat」ファイルのコマンドラインパラメーターを確認する方法

私のOSはWindows Vistaです。ユーザーがコマンドラインパラメーターを入力したかどうかを確認する必要がある「.bat」ファイルが必要です。その場合、パラメーターが-bに等しい場合、そうでない場合は「無効な入力」というフラグを立てます。ユーザーがコマンドラインパラメーターを入力しない場合は、何かを行います。次の.batファイルを作成しました。 -bおよび-bに等しくない場合に機能しますが、ユーザーがコマンドラインパラメーターを渡さないと失敗します。

私は常にエラーが発生します:

GOTO was unexpected at this time.

誰が私がここで間違っているのか教えてもらえますか?


ECHO OFF
CLS
ECHO.

IF [%1]==[/?] GOTO BLANK

IF %1=="-b" GOTO SPECIFIC

IF NOT %1=="-b" GOTO UNKNOWN

:SPECIFIC

ECHO SPECIFIC

GOTO DONE

:BLANK

ECHO No Parameter

GOTO DONE

:UNKNOWN

ECHO Unknown Option

GOTO DONE

:DONE

ECHO Done!
91
javauser71

パラメーターが空であることを確認する必要があります:if "%~1"=="" goto blank

完了したら、-bでif/elseスイッチを実行します:if "%~1"=="-b" (goto specific) else goto unknown

パラメータを引用符で囲むと、空白/空/欠落パラメータなどのチェックが簡単になります。 「〜」は、コマンドライン引数にある二重引用符が削除されることを保証します。

129
afrazier

http://ss64.com/nt/if.html で答えを探してください。コマンドはIF [%1]==[] GOTO NO_ARGUMENTまたは同様のものです。

26

短い答え-角かっこを使用します。

if [%1]==[] goto :blank

または(引用符で囲まれた引数を処理する必要がある場合は、以下の編集をご覧ください):

if [%~1]==[] goto :blank

どうして?あなたが尋ねるかもしれません。まあ、ジェレマイア・ウィルコックが言ったように: http://ss64.com/nt/if.html -彼らはそれを使用しています!わかりましたが、引用符の何が問題になっていますか?

繰り返しますが、短い答え:それらは「魔法の」ものです-時には二重(二重)引用符が単一(二重)引用符に変換されます。そして、彼らは最初に一致する必要があります。

次の小さなスクリプトを検討してください。

@rem argq.bat
@echo off

:loop 
if "%1"=="" goto :done
echo %1
shift
goto :loop

:done
echo Done.

テストしてみましょう:

C:\> argq bla bla
bla
bla
Done.

動作しているようです。しかし、今、2番目のギアに切り替えましょう。

C:\> argq "bla bla"
bla""=="" was unexpected at this time.

Boomこれはtrueと評価されず、falseと評価されませんでした。スクリプトは終了しました。もしラインのどこかで原子炉の電源を切ることになっていたなら、それは大変な運だ。あなたは今、ハリー・ダグリアンのように死ぬでしょう。

あなたは思うかもしれません-OK、引数に引用符を含めることはできません。もしそうなら、これは起こります。 間違っている慰めは以下のとおりです。

C:\> argq ""bla bla""
""bla
bla""
Done.

そうそう。心配しないでください-時々このは動作します

別のスクリプトを試してみましょう。

@rem args.bat
@echo off

:loop 
if [%1]==[] goto :done
echo %1
shift
goto :loop

:done
echo Done.

上記の場合に問題なく動作することをテストできます。これは論理的です-引用符は括弧とは関係ないので、ここには魔法はありません。しかし、引数を角括弧で味付けするのはどうですか?

D:\>args ]bla bla[
]bla
bla[
Done.

D:\>args [bla bla]
[bla
bla]
Done.

運がありません。ブラケットはcmd.exeのパーサーを止めることができません。

少し悪の引用に戻りましょう。引数が引用符で終わったとき、問題はそこにありました:

D:\>argq "bla1 bla2"
bla2""=="" was unexpected at this time.

合格した場合:

D:\>argq bla2"
The syntax of the command is incorrect.

スクリプトはまったく実行されません。 args.batについても同じ:

D:\>args bla2"
The syntax of the command is incorrect.

しかし、そのような場合に"-文字の数が「一致する」(つまり-偶数)とき、私は何を得るのですか:

D:\>args bla2" "bla3
bla2" "bla3
Done.

Nice-.batファイルがコマンドライン引数を分割する方法について何かを学んだことを願っています(ヒント:* bashとはまったく異なります)。上記の引数にはスペースが含まれています。ただし、引用符は自動的に削除されません。

Argq?それにどのように反応しますか?予想通り:

D:\>argq bla2" "bla3
"bla3"=="" was unexpected at this time.

だから-あなたが言う前に考えてください:「知っている?ただ引用符を使用してください。(私にとって、これはより良く見えるので)」。

編集

最近、この答えについてのコメントがありました-まあ、角括弧は引用された引数を渡し、引用されていないかのように扱うことを「処理できません」。

構文:

if "%~1"=="" (...)

二重引用符のおかげで新しく発見されたものではなく、最初と最後の文字が二重引用符である場合、引数変数から引用符を取り除くというきちんとした機能の表示です。

この「テクノロジー」は、角かっこでも同様に機能します。

if [%~1]==[] (...)

これを指摘するのは便利なことだったので、新しい答えにも賛成です。

最後に、二重引用符のファン、あなたの本には""という形式の引数が存在しますか、それとも空白ですか?ちょうどaskin ';)

14
Tomasz Gandor

私が購読している他の回答に加えて、IFコマンドの/Iスイッチの使用を検討することもできます。

.../Iスイッチは、指定されている場合、大文字と小文字を区別しない文字列比較を行うように指示します。

ユーザーにパラメーターを指定するために大文字と小文字を区別しない柔軟性を与えたい場合に役立つかもしれません。

IF /I "%1"=="-b" GOTO SPECIFIC
8
PA.

実際、他のすべての答えには欠陥があります。最も信頼できる方法は次のとおりです。

IF "%~1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

詳細な説明:

スペースと引用符で引数を渡すと、"%1"=="-b"を使用するとクラッシュが完全に解消されます。これは最も信頼性の低い方法です。

IF "%1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

C:\> run.bat "a b"

b""=="-b" was unexpected at this time.

[%1]==[-b]を使用すると、スペースや引用符でクラッシュすることはありませんが、引数が引用符で囲まれている場合は一致しません。

IF [%1]==[-b] (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

C:\> run.bat "-b"

(does not match, and jumps to UNKNOWN instead of SPECIFIC)

"%~1"=="-b"を使用することが最も信頼できます。 %~1は、引用符が存在する場合、その引用符を取り除きます。したがって、引用符の有無にかかわらず、引数なしでも機能します。

IF "%~1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

C:\> run.bat
C:\> run.bat -b
C:\> run.bat "-b"
C:\> run.bat "a b"

(all of the above tests work correctly)
5
wisbucky

文字列を比較しています。引数が省略された場合、%1はブランクに展開され、コマンドはたとえばIF =="-b" GOTO SPECIFICになります(これは構文エラーです)。文字列を引用符(または角括弧)で囲みます。

REM this is ok
IF [%1]==[/?] GOTO BLANK

REM I'd recommend using quotes exclusively
IF "%1"=="-b" GOTO SPECIFIC

IF NOT "%1"=="-b" GOTO UNKNOWN
5
Jeff Mercado