2011-02-10 185 views
72

我的操作系統是Windows Vista。我需要一個「.bat」文件,我需要檢查用戶是否輸入任何命令行參數。如果那麼如果參數等於-b那麼我會做一些事情,否則我會標記「無效輸入」。如果用戶沒有輸入任何命令行參數,我會做一些事情。我創建了以下.bat文件。它適用於-b並且不等於-b個案 - 但在用戶未傳遞任何命令行參數時失敗。如何檢查「.bat」文件中的命令行參數?

我總是得到錯誤:

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! 
+0

如果在其他兩個IF語句中添加括號(如在'GOTO BLANK`行中),是否解決了這個問題? – 2011-02-10 04:00:05

回答

89

您需要檢查的參數是空白:if "%~1"=="" goto blank

一旦你這樣做,然後做一個-b的if/else開關:if "%~1"=="-b" (goto specific) else goto unknown

周邊的帶引號的參數可以更輕鬆地檢查諸如空白/空白/缺失參數等內容。 「〜」確保如果雙引號位於命令行參數中,則雙引號將被剝離。

+0

這個工程!只有「其他」不被接受。我得到錯誤:'else'不被識別爲內部或外部命令,可操作程序或批處理文件。所以我增加了另一個IF,用於「不等於-b」的情況。感謝你及時的答覆。 – javauser71 2011-02-10 06:29:35

+5

ELSE必須與IF相同,或者必須直接放在括號後面 – jeb 2011-02-10 07:30:42

+4

如果%1包含空格,這似乎不適用於我,如果它是完整路徑可執行文件。請參閱[Jeremiah Willcock的回答](http://stackoverflow.com/a/4953226/1840078),該解決方案即使對於值爲空格的參數也適用。 – 2014-11-11 02:37:20

4

您正在比較字符串。如果省略參數,則%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 
6

除了其他的答案,這我同意,你可以考慮使用/I開關IF命令。

... the /I switch, if specified, says to do case insensitive string compares.

如果您想給用戶提供不區分大小寫的靈活性來指定參數,它可能會有所幫助。

IF /I "%1"=="-b" GOTO SPECIFIC 
7

簡短的回答 - 用方括號:

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

或(當你需要處理引用指定參數時,請參見下面的編輯):

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

爲什麼?你可能會問。那麼,就像Jeremiah Willcock提到的那樣: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. 

似乎工作。但現在,讓我們切換到第二檔:

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

這沒有評估爲真,也沒有評價它爲false。腳本DIED。如果你應該關閉反應堆的某個地方,好運氣。你現在會像Harry Daghlian一樣死去。

您可能認爲 - 好的,參數不能包含引號。如果他們這樣做,就會發生。 錯誤下面是一些安慰:

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. 

但我得到的,什麼時候" -characters數 「匹配」(即 - 爲偶數),在這種情況下:

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

NICE - 我希望你學到了一些關於.bat文件如何拆分它們的命令行參數的東西(提示:*它不完全像bash中那樣)。上面的參數包含一個空格。但報價不會自動剝離。

和argq?它對此有何反應?可以預見的是:

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

所以 - 想你之前說:「?知道什麼就用引號[因爲,對我來說,這看起來更好]」。

編輯

近日,有關於這個答案的評論 - 好,sqare括號「無法處理」引用傳遞參數和對待他們就像如果他們沒有報價。

語法:

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

是不是有些新發現憑藉雙引號的,但是從參數變量剝離報價的實用的功能的顯示,如果第一個和最後一個字符是一個雙引號。

這種「技術」的作品一樣好與方括號:

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

正是指出這一點有益的事情,所以我也給予好評的新的答案。

最後,雙引號的粉絲,你的書中是否存在形式爲""的參數,還是空白?只是要求;)

2

其實,所有其他答案都有缺陷。最可靠的方法是:

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]是更好,因爲它不會有空格和引號會崩潰,但如果參數用引號括起來它不會匹配。使用"%~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)