".Bat" फ़ाइल में कमांड लाइन पैरामीटर कैसे जांचें?


103

मेरा 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!

यदि आप GOTO BLANKअन्य दो IFकथनों में कोष्ठक ( पंक्ति की तरह ) जोड़ते हैं , तो क्या यह समस्या को ठीक करता है?
यिर्मयाह विलकॉक 4

जवाबों:


141

आपको पैरामीटर के रिक्त होने की जाँच करने की आवश्यकता है: if "%~1"=="" goto blank

एक बार जब आप ऐसा कर लेते हैं, तो एक करें / अन्यथा स्विच ऑन-बी: if "%~1"=="-b" (goto specific) else goto unknown

उद्धरण के साथ मापदंडों को घेरना, खाली / खाली / लापता पैरामीटर जैसी चीजों की जाँच को आसान बनाता है। "~" यह सुनिश्चित करता है कि कमांड लाइन तर्क पर दोहरे उद्धरण छीन लिए गए हैं।


यह काम!! केवल "और" स्वीकार नहीं किया जाता है। मुझे त्रुटि मिलती है: 'और' को आंतरिक या बाहरी कमांड, ऑपरेबल प्रोग्राम या बैच फ़ाइल के रूप में मान्यता नहीं दी जाती है। इसलिए मैंने "इफ-बी-बी" केस के लिए एक और आईएफ जोड़ा। त्वरित उत्तर के लिए धन्यवाद।
javauser71

7
ELSE को IF के समान लाइन पर होना चाहिए, या इसे सीधे ब्रैकेट के बाद होना चाहिए
jeb

4
यह मेरे लिए काम नहीं करता है यदि% 1 में रिक्त स्थान है, जो कि हो सकता है यदि यह निष्पादन योग्य के लिए पूर्ण पथ है। एक समाधान के लिए जेरेमिया विलकॉक का जवाब देखें जो उनके मूल्यों में रिक्त स्थान के साथ मापदंडों के लिए भी काम करता है।
मार्क ए। फिजराल्ड़

यह स्वीकार नहीं किया जाएगा यदि आपका तर्क एक है File, उस स्थिति में आपकी जाँच केवल existया होनी चाहिए not exist। यही कारण है कि आपके तर्कों को अच्छी तरह से परिभाषित किया जाना चाहिए, या बस शक्तियां या vbScript (यदि आप 80 के दशक में हैं ..) का उपयोग करें

1
इसके लिए विफल रहता है run.bat "a b""%1"==""अगर arg के पास जगह है तो क्रैश। देखें stackoverflow.com/a/46942471
wisbucky

27

को देखो http://ss64.com/nt/if.html एक जवाब के लिए; कमांड IF [%1]==[] GOTO NO_ARGUMENTया समान है।


1
इतना ही नहीं यह ALSO काम भी करता है! यह इसके विपरीत काम करता है "%1"==""। मुझे अपने स्वयं के उत्तर में विस्तार से बताना है।
टॉमस गैंडर

1
जब% 1 उद्धृत किया जाएगा, तो यह टूट जाएगा, उदा foo.bat "1st parameter" 2nd_param। देखें stackoverflow.com/questions/2541767/...
मैट Wilkie

[%1]==[-b]अगर arg को उद्धृत किया जाता है तो उपयोग करना मेल नहीं खाएगा। उदाहरण है run.bat "-b"। देखें stackoverflow.com/a/46942471
wisbucky

20

संक्षिप्त उत्तर - वर्ग कोष्ठक का उपयोग करें:

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.

काम करने लगता है। लेकिन अब, दूसरे गियर पर स्विच करने देता है:

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

बूम यह सच करने के लिए मूल्यांकन नहीं था, न ही यह गलत का मूल्यांकन किया था। स्क्रिप्ट DIED। यदि आप लाइन से नीचे रिएक्टर को बंद करने वाले थे, तो अच्छी तरह से - कठिन भाग्य। अब आप हैरी डागलियन की तरह मर जाएंगे।

आप सोच सकते हैं - ठीक है, तर्कों में उद्धरण शामिल नहीं हो सकते। यदि वे करते हैं, तो ऐसा होता है। गलत यहाँ कुछ सांत्वना है:

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फाइलें अपने कमांड लाइन के तर्कों को कैसे विभाजित करती हैं (HINT: * यह वास्तव में बैश की तरह नहीं है)। उपरोक्त तर्क में एक स्थान है। लेकिन उद्धरण स्वचालित रूप से छीन नहीं रहे हैं।

और अर्गक? यह उस पर कैसे प्रतिक्रिया करता है? जाहिर:

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

इसलिए - कहने से पहले सोचें: "पता है क्या? बस उद्धरण का उपयोग करें। [क्योंकि, मेरे लिए, यह अच्छा लग रहा है]"।

संपादित करें

हाल ही में, इस उत्तर के बारे में टिप्पणियां थीं - ठीक है, वर्गीय कोष्ठक "उद्धृत तर्कों को पारित नहीं कर सकते हैं और उनके साथ व्यवहार कर सकते हैं जैसे कि वे उद्धृत नहीं किए गए थे।

वाक्य रचना:

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

क्या दोहरे उद्धरण चिह्नों का कुछ नया पाया गया गुण नहीं है, लेकिन तर्क चर से अलग करने वाले उद्धरणों की एक स्वच्छ विशेषता का प्रदर्शन, यदि पहला और अंतिम चरित्र एक दोहरा उद्धरण है।

यह "तकनीक" वर्गाकार कोष्ठक के साथ ही काम करती है:

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

यह इंगित करने के लिए एक उपयोगी बात थी, इसलिए मैं नए उत्तर को भी प्रस्तुत करता हूं।

अंत में, डबल उद्धरण प्रशंसक, ""आपकी पुस्तक में फ़ॉर्म का एक तर्क मौजूद है, या क्या यह रिक्त है? यूं ही पूछ रहा था' ;)


1
[%1]==[-b]यदि वर्ग को उद्धृत किया जाता है तो स्क्वायर कोष्ठक मेल नहीं खाएंगे run.bat "-b"। देखें stackoverflow.com/a/46942471
wisbucky

ऐतिहासिक रूप से ध्यान दें: [%1]==[-b]और "%1"=="-b"98 और पहले के MS / PC-DOS सिस्टम बैच स्क्रिप्ट जीतने के लिए समान थे। 2000 जीतने के बाद से / NT ने वाक्य रचना की शुरुआत की if "%~1"=="-b"जहां दोहरे उद्धरण चिह्नों का विशेष अर्थ है कि आपको स्क्रिप्ट को कोड करना चाहिए क्योंकि यह अधिक मजबूत सुरक्षा प्रदान करता है। दोहरे उद्धरण विशेष वर्णों के अर्थ से बचते हैं (कोशिश करें और अपनी कमांड लाइन में% वर्ण)। 99.9% उदाहरण दोहरे उद्धरण वाक्य के साथ काम करते हैं - आपका उदाहरण argq bla2" "bla3केवल वर्ग कोष्ठक को सही ठहराने के लिए है। एंबेडेड डबल कोट्स आपदा के लिए एक नुस्खा है - सिर्फ कहते हैं
स्किप आर

@SkipR - यही कारण है कि विंडोज के फाइलसिस्टम में, आप इन विशेष वर्णों को नामों में नहीं रख सकते। मेरे पास कोई गणितीय प्रमाण नहीं है, लेकिन मुझे लगता है कि cmdशेल में बस सब कुछ उद्धृत नहीं किया जा सकता है (कुछ भागने के क्रम आदि के माध्यम से शब्दशः बनाया गया है) । अन्य प्रणालियों में आप कभी-कभी सब कुछ उद्धृत कर सकते हैं, एनयूएल वर्ण शामिल हैं। ( stackoverflow.com/questions/2730732/… ) - यह प्रश्न बस दिखाता है, आपको कुछ बाहरी प्रोग्राम का उपयोग करने की आवश्यकता है।
टॉमस गैंडर

8

अन्य उत्तरों के अलावा, जिनकी मैं सदस्यता लेता हूं, आप कमांड के /Iस्विच का उपयोग करने पर विचार कर सकते हैं IF

... / I स्विच, यदि निर्दिष्ट किया गया है, तो केस असंवेदनशील स्ट्रिंग तुलना करने के लिए कहता है।

यदि आप पैरामीटर को निर्दिष्ट करने के लिए अपने उपयोगकर्ताओं के लिए असंवेदनशील लचीलापन देना चाहते हैं तो यह मददगार हो सकता है।

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

5

आप तार की तुलना कर रहे हैं। यदि एक तर्क छोड़ दिया जाता है, %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

IF [% 1] == [/?] काम नहीं कर रहा है, लेकिन I IF [% 1] == [] या "% 1" == "" है, तो यह काम करता है। वैसे भी अब मैं जा सकता हूँ। अपनी त्वरित प्रतिक्रिया के लिए धन्यवाद।
javauser71

5

दरअसल, अन्य सभी उत्तरों में खामियां हैं। सबसे विश्वसनीय तरीका है:

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)

1
यह वर्ग कोष्ठक का अंत नहीं है, आप देखते हैं: IF [%~1]==[]- यह काम करता है, और यह भी संभालता है"-b" । आपको बस बॉक्स, erm, square [कोष्ठक] के अंदर सोचने में सक्षम होना चाहिए ।
टॉमस गैंडर

3

मैं हाल ही में बैच फ़ाइल में जटिल पैरामीटर स्विच के कार्यान्वयन के साथ संघर्ष कर रहा हूं इसलिए यहां मेरे शोध का परिणाम है। प्रदान किए गए उत्तर में से कोई भी पूरी तरह से सुरक्षित नहीं है, उदाहरण:

"%1"=="-?" अगर पैरामीटर उद्धरणों में संलग्न है (फ़ाइल नाम आदि के लिए आवश्यक) से मेल नहीं खाएगा या यदि पैरामीटर उद्धरणों में है और क्रैश होगा (फिर से अक्सर फ़ाइल नामों में देखा जाता है)

@ECHO OFF
SETLOCAL
echo.
echo starting parameter test...
echo.
rem echo First parameter is %1
if "%1"=="-?" (echo Condition is true, param=%1) else (echo Condition is false, param=%1)
C:\>test.bat -?

starting parameter test...

Condition is true, param=-?

C:\>test.bat "-?"

starting parameter test...

Condition is false, param="-?"

वर्ग कोष्ठक के साथ किसी भी संयोजन [%1]==[-?]या [%~1]==[-?]मामले में पैरामीटर विफल होने की स्थिति में उद्धरण के भीतर स्थान होगा:

@ECHO OFF
SETLOCAL 
echo.
echo starting parameter test...
echo.
echo First parameter is %1
if [%~1]==[-?] (echo Condition is true, param=%1) else (echo Condition is false, param=%1)

C:\>test.bat "long file name"

starting parameter test...

First parameter is "long file name"
file was unexpected at this time.

प्रस्तावित सबसे सुरक्षित समाधान "%~1"=="-?"एक जटिल पैरामीटर के साथ दुर्घटनाग्रस्त हो जाएगा जिसमें उद्धरण के बाहर पाठ और उद्धरण के भीतर रिक्त स्थान के साथ पाठ शामिल हैं:

@ECHO OFF
SETLOCAL 
echo.
echo starting parameter test...
echo.
echo First parameter is %1
if "%~1"=="-?" (echo Condition is true, param=%1) else (echo Condition is false, param=%1)

C:\>test.bat -source:"long file name"

starting parameter test...

First parameter is -source:"long file name"
file was unexpected at this time.

उपरोक्त सभी परिदृश्यों को सुनिश्चित करने का एकमात्र तरीका उपयोग करना है EnableDelayedExpansion और चर का उपयोग करके संदर्भ (मान से नहीं) द्वारा मापदंडों को पारित करें। तब भी सबसे जटिल परिदृश्य ठीक काम करेगा:

@ECHO OFF
SETLOCAL EnableDelayedExpansion
echo.
echo starting parameter test...
echo.
echo First parameter is %1
:: we assign the parameter to a variable to pass by reference with delayed expansion
set "var1=%~1"
echo var1 is !var1!
:: we assign the value to compare with to a second variable to pass by reference with delayed expansion
set "var2=-source:"c:\app images"\image.png"
echo var2 is !var2!
if "!var1!"=="!var2!" (echo Condition is true, param=!var1!) else (echo Condition is false, param=!var1!)
C:\>test.bat -source:"c:\app images"\image.png

starting parameter test...

First parameter is -source:"c:\app images"\image.png
var1 is -source:"c:\app images"\image.png
var2 is -source:"c:\app images"\image.png
Condition is true, param=-source:"c:\app images"\image.png

C:\>test.bat -source:"c:\app images"\image1.png

starting parameter test...

First parameter is -source:"c:\app images"\image1.png
var1 is -source:"c:\app images"\image1.png
var2 is -source:"c:\app images"\image.png
Condition is false, param=-source:"c:\app images"\image1.png

C:\>test.bat -source:"c:\app images\image.png"

starting parameter test...

First parameter is -source:"c:\app images\image.png"
var1 is -source:"c:\app images\image.png"
var2 is -source:"c:\app images"\image.png
Condition is false, param=-source:"c:\app images\image.png"

0

ऐसा करने के लिए Windows बैच में DEFINED कीवर्ड है।

IF DEFINED %~1 foo
IF NOT DEFINED %~1 bar

धन्यवाद डेविड। मुझे नहीं पता कि आईएफ और आईएफ नॉट के बीच कैरिज रिटर्न और नई लाइन बनने में असफल क्यों रहा। मैंने भी गौर नहीं किया।
चार्ल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.