วิธีที่เหมาะสมในการทดสอบว่าพารามิเตอร์ว่างเปล่าในไฟล์แบตช์คืออะไร?


213

ฉันต้องการทดสอบว่ามีการตั้งค่าตัวแปรหรือไม่ ฉันได้พยายามใช้เทคนิคหลายอย่าง แต่พวกเขาดูเหมือนจะล้มเหลวเมื่อใดก็ตามที่%1ถูกล้อมรอบด้วยคำพูดเช่นกรณีที่เป็น%1"c:\some path with spaces"

IF NOT %1 GOTO MyLabel // This is invalid syntax
IF "%1" == "" GOTO MyLabel // Works unless %1 has double quotes which fatally kills bat execution
IF %1 == GOTO MyLabel // Gives an unexpected GOTO error.

ตามเว็บไซต์นี้เป็นIFประเภทไวยากรณ์ที่รองรับ ดังนั้นฉันไม่เห็นวิธีที่จะทำ

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command

1
ในระบบของฉัน (Windows 2003 และ Windows 7) if "%1" == "" GOTO MyLabelจะไม่ฆ่าการดำเนินการของสคริปต์อย่างร้ายแรงตราบใดที่%1ยังมีเครื่องหมายคำพูดคู่ ฉันเห็นว่ามีเครื่องหมายคำพูดคู่จำนวนมาก%1ฆ่าการเรียกใช้สคริปต์ด้วยข้อผิดพลาดนี้: The syntax of the command is incorrect.การแก้ปัญหาด้านล่างที่ใช้วงเล็บเหลี่ยมเพื่อแก้ปัญหาได้รับการทำเครื่องหมายว่าเป็นคำตอบที่ถูกต้อง แต่ดูเหมือนจะไม่ดีขึ้น . การแก้ปัญหานั้นก็ล้มเหลวด้วยข้อผิดพลาดเดียวกันเมื่อ%1มีจำนวนคู่ของคำพูดคู่
Susam Pal

@SusamPal ที่น่าสนใจ ลองรุ่นวงเล็บใต้และดูว่ามันใช้งานได้หรือไม่ ที่หนึ่งฉันทดสอบเพิ่มเติม ฉันเพิ่งอัปเดตคำตอบที่ยอมรับเมื่อสองสามวันก่อน
blak3r

คำตอบของ Dan Storyดูเหมือนจะทำงานได้ดีอย่างแน่นอน ฉันใช้เวอร์ชันโดยใช้วงเล็บเหลี่ยม
Susam Pal

ตัวอย่าง "catch all" ที่ดี: stackoverflow.com/questions/830565/…ครอบคลุมทั้งไฟล์ / ไดเรกทอรีและการผสมสตริง / หมายเลขทั่วไปในการโต้แย้ง

น่าหงุดหงิด - IF DEFINEDการทำงานกับตัวแปรสภาพแวดล้อมแทนที่จะเป็นตัวแปรสคริปต์เท่านั้นคือการสูญเสียศักยภาพ!
kayleeFrye_onDeck

คำตอบ:


290

ใช้วงเล็บเหลี่ยมแทนเครื่องหมายคำพูด:

IF [%1] == [] GOTO MyLabel

วงเล็บไม่ปลอดภัย : ใช้วงเล็บเหลี่ยมเท่านั้น


11
วงเล็บไม่ปลอดภัย! เนื้อหาเช่น&ใน%1จะแบ่งสาย
Jeb

14
การใช้อักขระอื่น ๆ เช่นif #%1#==##หรือif [%1]==[]ดีตราบใดที่ไม่มีช่องว่างในการโต้แย้งมิฉะนั้นคุณจะได้รับ…was unexpected at this timeข้อผิดพลาด
Synetech

12
และการใช้"%~1"เป็นวิธีที่ดีกว่าอย่างที่ฉันได้กล่าวไว้ในคำตอบของฉัน
jamesdlin

8
Guys, @jamesdlin ถูกต้อง ==วิธีการนี้จะไม่ทำงานหากข้อความตัวแปรมีช่องว่างหรือเป็น ใช้คำตอบของเขาแทน
James Ko

4
it DOES NOT work with spacesคุณไม่ทำให้มันชัดเจนว่า ใช้คำตอบ @jamesdlin แทน
JB กับโมนิก้า

153

คุณสามารถใช้ได้:

IF "%~1" == "" GOTO MyLabel

เพื่อตัดชุดคำพูดภายนอก โดยทั่วไปนี่เป็นวิธีที่เชื่อถือได้มากกว่าการใช้วงเล็บเหลี่ยมเพราะมันจะทำงานแม้ว่าตัวแปรจะมีช่องว่างอยู่ก็ตาม


9
นี่เป็นวิธีที่ดีที่จะทำ โดยการใช้~คุณสามารถตัดเครื่องหมายอัญประกาศด้านนอกถ้ามีอยู่แล้วเพิ่มกลับด้วยตนเอง (สร้างความมั่นใจเพียงชุดเดียว) ยิ่งกว่านั้นคุณต้องใช้เครื่องหมายอัญประกาศถ้าอาร์กิวเมนต์มีช่องว่าง (ฉันเรียนรู้วิธีนี้อย่างยากลำบากเมื่อเวอร์ชันก่อนหน้าของฉันในการใช้งาน#หรือวงเล็บแทนคำพูดทำให้เกิดการขัดแย้งกับช่องว่างเพื่อโยน…was unexpected at this timeข้อผิดพลาด)
Synetech

4
สิ่งนี้ใช้กับตัวแปรทั่วไปเช่น% MYVAR% แทนที่จะใช้อาร์กิวเมนต์เช่น% 1 ได้หรือไม่
simpleuser

4
@simpleuser อ๊ะคุณพูดถูกมันไม่ทำงานกับตัวแปรสภาพแวดล้อมทั่วไป
jamesdlin

1
ระวังสตริงที่ใช้ double '"' เป็น escape sequence - สคริปต์จะทำงานผิดพลาดเมื่อพยายามทำการเปรียบเทียบเช่น""this string will crash the comparison""double" "'เป็น escape escape ที่เหมาะสมและการแทนที่ด้วย double'" 'จะล้มเหลวหาก สตริงว่างเปล่า
Tydaeus

1
@Amalgovinus "%~1"คุณอาจจะผ่านตัวแปรเป็นอาร์กิวเมนต์ย่อยและให้ใช้
jamesdlin

38

หนึ่งในโซลูชั่นกึ่งดีที่สุดคือการคัดลอก%1ลงในตัวแปรและจากนั้นใช้การขยายที่ล่าช้าเช่นล่าช้า ปลอดภัยต่อเนื้อหาใด ๆ เสมอ

set "param1=%~1"
setlocal EnableDelayedExpansion
if "!param1!"=="" ( echo it is empty )
rem ... or use the DEFINED keyword now
if defined param1 echo There is something

ข้อดีของการทำเช่นนี้คือการจัดการกับ param1 นั้นปลอดภัยอย่างแท้จริง

และการตั้งค่าของ param1 จะทำงานในหลายกรณีเช่น

test.bat hello"this is"a"test
test.bat you^&me

แต่มันก็ล้มเหลวด้วยเนื้อหาแปลก ๆ เช่น

test.bat ^&"&

เพื่อให้สามารถได้รับคำตอบที่ถูกต้อง 100% สำหรับการดำรงอยู่

ตรวจพบว่า%1ว่างเปล่า แต่สำหรับเนื้อหาบางส่วนจะไม่สามารถดึงเนื้อหาได้
นี้ยังสามารถเป็นประโยชน์ในการแยกแยะความแตกต่างระหว่างที่ว่างเปล่าและเป็นหนึ่งเดียวกับ%1 มันใช้ความสามารถของคำสั่งที่จะล้มเหลวโดยไม่ยกเลิกไฟล์แบทช์""
CALL

@echo off
setlocal EnableDelayedExpansion
set "arg1="
call set "arg1=%%1"

if defined arg1 goto :arg_exists

set "arg1=#"
call set "arg1=%%1"
if "!arg1!" EQU "#" (
    echo arg1 exists, but can't assigned to a variable
    REM Try to fetch it a second time without quotes
    (call set arg1=%%1)
    goto :arg_exists
)

echo arg1 is missing
exit /b

:arg_exists
echo arg1 exists, perhaps the content is '!arg1!'

หากคุณต้องการเป็นตัวแสดงหัวข้อย่อย 100% เพื่อดึงเนื้อหาคุณสามารถอ่านวิธีรับแม้พารามิเตอร์บรรทัดคำสั่งที่แปลกที่สุด?


18

จาก IF /?:

หากส่วนขยายคำสั่งถูกเปิดใช้งานหากมีการเปลี่ยนแปลงดังต่อไปนี้:

IF [/I] string1 compare-op string2 command
IF CMDEXTVERSION number command
IF DEFINED variable command

......

เงื่อนไข DEFINED ทำงานเหมือนกับ EXISTS ยกเว้นจะใช้ชื่อตัวแปรสภาพแวดล้อมและส่งกลับค่าจริงถ้ากำหนดตัวแปรสภาพแวดล้อม


1
ใช่ฉันลองใช้วิธีการนี้จริง ๆ แล้วและจากสิ่งที่ฉันสามารถบอกได้ว่าสิ่งนี้ใช้ได้กับตัวแปรสภาพแวดล้อมเท่านั้น ดังนั้นจึงไม่สามารถใช้งานได้กับ% 1 หรือตัวแปรที่กำหนดไว้ในไฟล์แบตช์
blak3r

2
นั่นเป็นเพียงความจริง%1และชอบ "ตัวแปรที่กำหนดภายในไฟล์แบทช์" จริงๆแล้วคือตัวแปรสภาพแวดล้อมในขณะที่ไฟล์แบตช์กำลังทำงานและคุณสามารถใช้IF DEFINEDกับมันได้
zb226

8

น่าเสียดายที่ฉันไม่มีชื่อเสียงพอที่จะแสดงความคิดเห็นหรือลงคะแนนให้กับคำตอบปัจจุบันที่ฉันต้องเขียนเอง

แต่เดิมคำถามของ OP กล่าวว่า "ตัวแปร" แทนที่จะเป็น "พารามิเตอร์" ซึ่งสร้างความสับสนอย่างมากโดยเฉพาะอย่างยิ่งเนื่องจากเป็นลิงก์อันดับหนึ่งใน google สำหรับค้นหาวิธีทดสอบตัวแปรว่าง ตั้งแต่คำตอบดั้งเดิมของฉันสเตฟานได้แก้ไขคำถามเดิมเพื่อใช้คำศัพท์ที่ถูกต้อง แต่แทนที่จะลบคำตอบของฉันฉันตัดสินใจที่จะปล่อยให้มันช่วยล้างความสับสนโดยเฉพาะอย่างยิ่งในกรณีที่ google ยังคงส่งคนมาที่นี่ด้วยเช่นกัน:

% 1 ไม่ใช่ตัวแปร! มันเป็นพารามิเตอร์บรรทัดคำสั่ง

ความแตกต่างที่สำคัญมาก เครื่องหมายเปอร์เซ็นต์เดียวที่มีตัวเลขหลังจากนั้นอ้างถึงพารามิเตอร์บรรทัดคำสั่งไม่ใช่ตัวแปร

ตัวแปรถูกตั้งค่าโดยใช้คำสั่ง set และถูกเรียกคืนโดยใช้เครื่องหมาย 2 เปอร์เซ็นต์ - หนึ่งก่อนและหนึ่งหลังจากนั้น ตัวอย่างเช่น% myvar%

ในการทดสอบตัวแปรว่างคุณใช้ไวยากรณ์ "ถ้าไม่ได้กำหนด" (คำสั่งอย่างชัดเจนสำหรับตัวแปรไม่จำเป็นต้องมีเครื่องหมายเปอร์เซ็นต์ใด ๆ ) ตัวอย่างเช่น:

set myvar1=foo  
if not defined myvar1 echo You won't see this because %myvar1% is defined.  
if not defined myvar2 echo You will see this because %myvar2% isn't defined.

(ถ้าคุณต้องการทดสอบพารามิเตอร์บรรทัดคำสั่งฉันแนะนำให้อ้างอิงถึงคำตอบของ jamesdlin)


1
คุณพูดถูก แต่วิธีที่ถูกต้องจะได้รับเพียงแค่แก้ไขชื่อจากไปif variable is empty if parameter is emptyฉันแค่ทำมัน (ที่มีความเสี่ยงที่จะเป็นโมฆะบางคำตอบที่ได้ตรวจสอบตัวแปรแทนของพารามิเตอร์และเพื่อให้มีอยู่แล้วที่ไม่ถูกต้องเช่นที่พวกเขาไม่ได้ตอบคำถาม)
สเตฟาน

1
โอเคขอบคุณสเตฟานไม่รู้ว่าคุณทำได้ ฉันได้แก้ไขคำตอบเพื่อให้สอดคล้องกับการอัพเดท
AutoMattTick

6

ใช้คำสั่ง "IF DEFINED variable" เพื่อทดสอบตัวแปรในไฟล์แบตช์

แต่ถ้าคุณต้องการทดสอบพารามิเตอร์แบตช์ให้ลองรหัสด้านล่างเพื่อหลีกเลี่ยงการป้อนข้อมูลที่ยุ่งยาก (เช่น "1 2" หรือ ab ^> cd)

set tmp="%1"
if "%tmp:"=.%"==".." (
    echo empty
) else (
    echo not empty
)

5

ฉันทดสอบด้วยโค้ดด้านล่างและก็ใช้ได้

@echo off

set varEmpty=
if not "%varEmpty%"=="" (
    echo varEmpty is not empty
) else (
    echo varEmpty is empty
)
set varNotEmpty=hasValue
if not "%varNotEmpty%"=="" (
    echo varNotEmpty is not empty
) else (
    echo varNotEmpty is empty
)

โซลูชันของคุณล้มเหลวเมื่อตัวแปรมีเครื่องหมายคำพูด Btw มีไวยากรณ์IF DEFINED varสำหรับเหตุผลอยู่
jeb

4

ฉันมักจะใช้สิ่งนี้:

IF "%1."=="." GOTO MyLabel

หาก% 1 ว่างเปล่า IF จะทำการเปรียบเทียบ "." ถึง "." ซึ่งจะประเมินเป็นจริง


4
สิ่งนี้ไม่ถูกต้อง นี่เป็นสิ่งเดียวกันกับ: ถ้า "% 1" == "" เหตุผลของการโพสต์นี้ก็คือถ้า% 1 ตัวเองมีเครื่องหมายคำพูดนี้ล้มเหลว
blak3r

คุณกำลังพยายามทดสอบว่า% 1 ว่างเปล่าหรือมีเครื่องหมายคำพูดหรือไม่? คำถามไม่ชัดเจน คำตอบของฉันใช้งานได้หากไม่มีการระบุอะไรในบรรทัดคำสั่งสำหรับ% 1
aphoria

> คุณพยายามทดสอบว่า% 1 ว่างเปล่าหรือมีราคาหรือไม่? @aphoria มันจะต้องสามารถจัดการได้ทั้งคู่
Synetech

ฉันใช้สิ่งนี้เพื่อทำงานถ้า% 1% ได้รับการตั้งค่าทำงานได้ดีสำหรับฉัน ขอบคุณคำตอบที่ดี!
Charlie

4

ฉันสร้างสคริปต์ชุดเล็กนี้ขึ้นอยู่กับคำตอบที่นี่เนื่องจากมีหลายรายการที่ถูกต้อง อย่าลังเลที่จะเพิ่มสิ่งนี้ตราบใดที่คุณทำตามรูปแบบเดียวกัน:

REM Parameter-testing

Setlocal EnableDelayedExpansion EnableExtensions

IF NOT "%~1"=="" (echo Percent Tilde 1 failed with quotes) ELSE (echo SUCCESS)
IF NOT [%~1]==[] (echo Percent Tilde 1 failed with brackets) ELSE (echo SUCCESS)
IF NOT  "%1"=="" (echo Quotes one failed) ELSE (echo SUCCESS)
IF NOT [%1]==[] (echo Brackets one failed) ELSE (echo SUCCESS)
IF NOT "%1."=="." (echo Appended dot quotes one failed) ELSE (echo SUCCESS)
IF NOT [%1.]==[.] (echo Appended dot brackets one failed) ELSE (echo SUCCESS)

pause

4

สตริงว่างคือคู่ของdouble-quotes/ "", เราสามารถทดสอบความยาวได้:

set ARG=%1
if not defined ARG goto nomore

set CHAR=%ARG:~2,1%
if defined CHAR goto goon

จากนั้นทดสอบว่าเป็นอักขระ 2 ตัวกับdouble-quotes:

if ^%ARG:~1,1% == ^" if ^%ARG:~0,1% == ^" goto blank
::else
goto goon

นี่คือแบทช์สคริปต์ที่คุณสามารถเล่นได้ ฉันคิดว่ามันจับสตริงว่างได้ถูกต้อง

นี่เป็นเพียงตัวอย่างคุณเพียงแค่ต้องปรับแต่งขั้นตอน 2 (หรือ 3?) ด้านบนตามสคริปต์ของคุณ

@echo off
if not "%OS%"=="Windows_NT" goto EOF
:: I guess we need enableExtensions, CMIIW
setLocal enableExtensions
set i=0
set script=%0

:LOOP
set /a i=%i%+1

set A1=%1
if not defined A1 goto nomore

:: Assumption:
:: Empty string is (exactly) a pair of double-quotes ("")

:: Step out if str length is more than 2
set C3=%A1:~2,1%
if defined C3 goto goon

:: Check the first and second char for double-quotes
:: Any characters will do fine since we test it *literally*
if ^%A1:~1,1% == ^" if ^%A1:~0,1% == ^" goto blank
goto goon

:goon
echo.args[%i%]: [%1]
shift
goto LOOP

:blank
echo.args[%i%]: [%1] is empty string
shift
goto LOOP

:nomore
echo.
echo.command line:
echo.%script% %*

:EOF

ผลการทดสอบการทรมานนี้:

.test.bat :: ""  ">"""bl" " "< "">"  (")(") "" :: ""-"  " "( )"">\>" ""
args[1]: [::]
args[2]: [""] is empty string
args[3]: [">"""bl" "]
args[4]: ["< "">"]
args[5]: [(")(")]
args[6]: [""] is empty string
args[7]: [::]
args[8]: [""-"  "]
args[9]: ["( )"">\>"]
args[10]: [""] is empty string

command line:
.test.bat :: ""  ">"""bl" " "< "">"  (")(") "" :: ""-"  " "( )"">\>" ""

เป็นความผิดพลาดสตริงว่างเปล่าไม่ใช่สตริงที่มีเครื่องหมายคำพูดคู่สอง""ตัวสตริงว่างเปล่าเป็นสตริงว่าง `` และในชุดตัวแปรว่างเปล่าเป็นตัวแปรที่ไม่ได้กำหนด คุณสามารถกำหนดได้ว่าสำหรับอาร์กิวเมนต์ของคุณเครื่องหมายอัญประกาศด้านนอกจะถูกลบออก แต่สตริงนั้นยังคงว่างเปล่าด้วยความยาว 0
jeb

ในบริบทนี้ (ชนะ cmd อาร์กิวเมนต์) คุณไม่สามารถแสดงสตริงว่างด้วยวิธีอื่น ๆ ได้แม้จะมีเครื่องหมายคำพูดเดี่ยวคู่ซึ่งว่างเปล่าเท่ากันภายใต้เชลล์ unix
user6801759

ใช่""ใช้สำหรับสตริงว่างเช่นกัน แต่มันค่อนข้างง่ายที่%~1จะลบเครื่องหมายคำพูดภายนอก ไม่จำเป็นต้องใช้วิธีแก้ปัญหาที่ซับซ้อนเช่นนี้
jeb

คุณถูกต้องฉันอาจระบุไว้ไม่ถูกต้องไม่ใช่เฉพาะกับสตริงว่าง แต่เป็นวิธีที่ปลอดภัยในการระบุอาร์กิวเมนต์ วิธีอื่นเช่น"%~1"==""จะล้มเหลวด้วยการโต้แย้ง"Long File Name".txtซึ่งเป็นอาร์กิวเมนต์ที่ถูกต้อง แก้ไข : และมันไม่ซับซ้อนอย่างที่คุณพูด เพียง 2 ขั้นตอนสำหรับการทดสอบส่วนที่เหลือเป็นตัวอย่างที่ชัดเจน
user6801759

"ถ้าไม่ได้กำหนด ARG" ดูเหมือนว่าจะทำงานได้อย่างสมบูรณ์แบบ (ตัวแปรของฉันไม่ได้มาจากบรรทัดคำสั่ง)
GrayFace

4

คุณสามารถใช้ได้

if defined (variable) echo That's defined!
if not defined (variable) echo Nope. Undefined.

1
ยินดีต้อนรับสู่ SO! คำตอบของคุณดูเหมือนจะเป็นคำตอบที่ดีสำหรับคำถาม เมื่อคุณมี [ชื่อเสียง] เพียงพอ ( stackoverflow.com/help/whats-reputation ) คุณจะสามารถแสดงความคิดเห็นในโพสต์ใด ๆ ได้ นอกจากนี้ยังตรวจสอบเรื่องนี้สิ่งที่ฉันจะทำแทน
อีก

3

สคริปต์ 1:

ป้อนข้อมูล ("ลบ Quotes.cmd" "นี่คือการทดสอบ")

@ECHO OFF

REM Set "string" variable to "first" command line parameter
SET STRING=%1

REM Remove Quotes [Only Remove Quotes if NOT Null]
IF DEFINED STRING SET STRING=%STRING:"=%

REM IF %1 [or String] is NULL GOTO MyLabel
IF NOT DEFINED STRING GOTO MyLabel


REM   OR   IF "." equals "." GOTO MyLabel
IF "%STRING%." == "." GOTO MyLabel

REM GOTO End of File
GOTO :EOF

:MyLabel
ECHO Welcome!

PAUSE

เอาท์พุท (ไม่มี,% 1 ไม่ว่างเปล่าว่างเปล่าหรือเป็นโมฆะ):


รัน ("Remove Quotes.cmd") โดยไม่มีพารามิเตอร์ใด ๆ ด้วยสคริปต์ด้านบน 1

เอาท์พุท (% 1 ว่างเปล่าว่างเปล่าหรือ NULL):

Welcome!

Press any key to continue . . .

หมายเหตุ: หากคุณตั้งค่าตัวแปรภายในIF ( ) ELSE ( )คำสั่งจะไม่สามารถกำหนด DEFINED จนกว่าจะออกจากคำสั่ง "IF" (เว้นแต่ว่าจะเปิดใช้งาน "การขยายตัวแปรล่าช้า" เปิดใช้งานเมื่อใช้เครื่องหมายอัศเจรีย์ "!" แทน) เครื่องหมายเปอร์เซ็นต์ "%"}

ตัวอย่างเช่น:

บทที่ 2:

ป้อนข้อมูล ("ลบ Quotes.cmd" "นี่คือการทดสอบ")

@ECHO OFF

SETLOCAL EnableDelayedExpansion

SET STRING=%0
IF 1==1 (
  SET STRING=%1
  ECHO String in IF Statement='%STRING%'
  ECHO String in IF Statement [delayed expansion]='!STRING!'
) 

ECHO String out of IF Statement='%STRING%'

REM Remove Quotes [Only Remove Quotes if NOT Null]
IF DEFINED STRING SET STRING=%STRING:"=%

ECHO String without Quotes=%STRING% 

REM IF %1 is NULL GOTO MyLabel
IF NOT DEFINED STRING GOTO MyLabel

REM GOTO End of File
GOTO :EOF

:MyLabel
ECHO Welcome!

ENDLOCAL
PAUSE

เอาท์พุท:

C:\Users\Test>"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd" "This is a Test"  
String in IF Statement='"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"'  
String in IF Statement [delayed expansion]='"This is a Test"'  
String out of IF Statement='"This is a Test"'  
String without Quotes=This is a Test  

C:\Users\Test>  

หมายเหตุ: มันจะลบเครื่องหมายคำพูดออกจากภายในสตริงด้วย

ตัวอย่างเช่น (ใช้สคริปต์ 1 หรือ 2): ไฟล์ C: \ Users \ Test \ Documents \ Batch> "Remove Quotes.cmd" "นี่คือ" a "ทดสอบ"

ผลลัพธ์ (สคริปต์ 2):

String in IF Statement='"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"'  
String in IF Statement [delayed expansion]='"This is "a" Test"'  
String out of IF Statement='"This is "a" Test"'  
String without Quotes=This is a Test  

ดำเนินการ ("ลบ Quotes.cmd") โดยไม่มีพารามิเตอร์ใด ๆ ในสคริปต์ 2:

เอาท์พุท:

Welcome!

Press any key to continue . . .

3

เพื่อสรุปสิ่งต่างๆ:

set str=%~1
if not defined str ( echo Empty string )

รหัสนี้จะแสดงผล "สตริงว่าง" หาก% 1 เป็น "" หรือ "หรือว่างเปล่าเพิ่มเข้าไปในคำตอบที่ยอมรับซึ่งปัจจุบันไม่ถูกต้อง


0

ฉันมีปัญหามากมายพร้อมคำตอบมากมายบนเน็ต งานส่วนใหญ่สำหรับสิ่งต่าง ๆ แต่มีมุมที่แตกต่างกันอยู่เสมอ
บางทีมันอาจไม่ทำงานถ้ามันมีอัญประกาศบางทีมันอาจแตกถ้ามันไม่มีอัญประกาศข้อผิดพลาดทางไวยากรณ์ถ้า var มีช่องว่างบางอันจะใช้ได้กับพารามิเตอร์เท่านั้น (ซึ่งต่างกับตัวแปรสภาพแวดล้อม) เทคนิคอื่น ๆ อนุญาตให้ว่าง ชุดของราคาที่จะผ่านตามที่กำหนดไว้และบางคนที่มีเล่ห์เหลี่ยมจะไม่ยอมให้คุณโซ่elseหลังจากนั้น

นี่เป็นวิธีแก้ปัญหาที่ฉันมีความสุขโปรดแจ้งให้เราทราบหากคุณพบว่ามีมุมเล็ก ๆ น้อย ๆ ที่ไม่สามารถใช้งานได้

:ifSet
if "%~1"=="" (Exit /B 1) else (Exit /B 0)

การมีรูทีนย่อยนั้นในสคริปต์ของคุณหรือเป็นของตัวเอง.batควรจะทำงานได้
ดังนั้นถ้าคุณต้องการที่จะเขียน (ในหลอก):

if (var)
then something
else somethingElse

คุณสามารถเขียน:

(Call :ifSet %var% && (
    Echo something
)) || (
    Echo something else
)

มันใช้งานได้สำหรับการทดสอบทั้งหมดของฉัน:

(Call :ifSet && ECHO y) || ECHO n
(Call :ifSet a && ECHO y) || ECHO n
(Call :ifSet "" && ECHO y) || ECHO n
(Call :ifSet "a" && ECHO y) || ECHO n
(Call :ifSet "a a" && ECHO y) || ECHO n

Echo'd n, y, n, y,y


ตัวอย่างเพิ่มเติม:

  • ต้องการตรวจสอบifหรือไม่Call :ifSet %var% && Echo set
  • ถ้าไม่ใช่ (แค่อย่างอื่น)? Call :ifSet %var% || Echo set
  • การตรวจสอบอาร์กิวเมนต์ที่ส่งผ่าน ทำงานได้ดีCall :ifSet %1 && Echo set
  • ไม่ต้องการที่จะอุดตันสคริปต์ / รหัส dupe ของคุณดังนั้นคุณจึงใส่มันเป็นของตัวเองifSet.bat? ไม่มีปัญหา:((Call ifSet.bat %var%) && Echo set) || (Echo not set)

พบกรณี; หากคุณลองไวยากรณ์ if with else และคำสั่งสุดท้ายในบล็อกนั้นล้มเหลวคำสั่งอื่นจะดำเนินการ: (Call ifSet.bat YES && (Echo true & Echo x | findstr y)) || Echo, echos true และ false
Hashbrown

ที่จริงแล้วถ้านี่เป็นปัญหาและคุณสามารถจัดการกับบรรทัดพิเศษคุณสามารถลดสิ่งนี้ได้ด้วยการโทรifSetด้วยตัวเองแล้วใช้If %errorlevel% EQU 0 (x) Else (y)
Hashbrown

กรณีใดบ้างที่คำตอบที่ยอมรับ (ใช้วงเล็บเหลี่ยม) ไม่ทำงาน? และคุณสามารถอธิบายสิ่งที่ Exit / B ทำได้
blak3r

ด้วยเหตุผลบางอย่างเมื่อฉันทดสอบมันแตกเมื่อใช้setตัวแปร (เช่น[%bob%]ทำงานเพื่ออาร์กิวเมนต์เช่นเดียว[%2]) แต่ตอนนี้ตรวจสอบอีกครั้งมันทำงาน ฉันเดาว่าสิ่งเดียวที่จับได้ใน[]ตอนนี้คือมันช่วยให้ใบเสนอราคาว่างเปล่าผ่านไปในขณะที่สิ่งนี้จะไม่เกิดขึ้น (ดังนั้นจึงขึ้นอยู่กับการใช้งานของคุณจริง ๆ )
Hashbrown

การ/Bตั้งค่าสถานะจะหยุดชุดข้อมูลทั้งหมดจากการออกเฉพาะการออกจากรูทีนย่อยหรือcallแบตช์ หากคุณไม่ได้ถามว่าคำสั่งทั้งหมดกำลังทำอะไรอยู่ มันกำลังส่งคืนรหัสข้อผิดพลาดเพื่อให้สคริปต์การโทรทราบผลของรูทีนย่อย ( 0ผ่าน, 1ล้มเหลว), ใช้งานได้ผ่านตรรกะบูลีนในคำตอบหรือผ่านทาง%errorlevel%ความคิดเห็นด้านบน
Hashbrown

0

ใช้งาน! แทน "สำหรับการตรวจสอบสตริงว่าง

@echo off
SET a=
SET b=Hello
IF !%a%! == !! echo String a is empty
IF !%b%! == !! echo String b is empty

1
เคล็ดลับไม่ดีจริงๆ เครื่องหมายคำพูดสามารถจัดการช่องว่างและอักขระพิเศษอย่างน้อยที่สุด แต่เครื่องหมายอัศเจรีย์ไม่สามารถทำได้ และเครื่องหมายอัศเจรีย์น่ารังเกียจจริงๆที่นี่เมื่อเปิดใช้งานการขยายล่าช้า
jeb

0

ฉันเพิ่งอายุไม่ถึงเดือน (แม้ว่าจะถูกถามเมื่อ 8 ปีก่อน) ... ฉันหวังว่าตอนนี้เขา / เธอจะย้ายไฟล์แบตช์ไปแล้ว ;-) ฉันเคยทำมันตลอดเวลา ฉันไม่แน่ใจว่าเป้าหมายสูงสุดคืออะไร ถ้า s / เขาขี้เกียจเช่นฉัน go.bat ของฉันจะทำงานเพื่ออะไรแบบนั้น (ดูด้านล่าง) แต่ 1 คำสั่งใน OP อาจไม่ถูกต้องหากคุณใช้อินพุตเป็นคำสั่งโดยตรง กล่าวคือ

"C:/Users/Me"

เป็นคำสั่งที่ไม่ถูกต้อง (หรือเคยเป็นหากคุณอยู่ในไดรฟ์อื่น) คุณต้องแบ่งมันเป็นสองส่วน

C:
cd /Users/Me

และ, 2, 'นิยาม' หรือ 'ไม่ได้กำหนด' หมายถึงอะไร? gigo ฉันใช้ค่าเริ่มต้นเพื่อตรวจจับข้อผิดพลาด หากอินพุตไม่ถูกดักจับก็จะลดลงเพื่อช่วย (หรือคำสั่งเริ่มต้น) ดังนั้นไม่มีอินพุตไม่ใช่ข้อผิดพลาด คุณสามารถลองซีดีไปที่อินพุตและตรวจจับข้อผิดพลาดหากมี (ตกลงโดยใช้ go "ดาวน์โหลด (หนึ่ง paren เท่านั้น) ถูกจับโดย DOS (Harsh!))

cd "%1"
if %errorlevel% neq 0 goto :error

และ 3 จำเป็นต้องใช้เครื่องหมายคำพูดรอบ ๆ พา ธ ไม่ใช่คำสั่ง กล่าวคือ

"cd C:\Users" 

ไม่ดี (หรือเคยเป็นในอดีต) เว้นแต่คุณจะอยู่ในไดรฟ์อื่น

cd "\Users" 

ทำงานได้

cd "\Users\Dr Whos infinite storage space"

ทำงานถ้าคุณมีช่องว่างในเส้นทางของคุณ

@REM go.bat
@REM The @ sigh prevents echo on the current command
@REM The echo on/off turns on/off the echo command. Turn on for debugging
@REM You can't see this.
@echo off
if "help" == "%1" goto :help

if "c" == "%1" C:
if "c" == "%1" goto :done

if "d" == "%1" D:
if "d" == "%1" goto :done

if "home"=="%1" %homedrive%
if "home"=="%1" cd %homepath%
if "home"=="%1" if %errorlevel% neq 0 goto :error
if "home"=="%1" goto :done

if "docs" == "%1" goto :docs

@REM goto :help
echo Default command
cd %1
if %errorlevel% neq 0 goto :error
goto :done

:help
echo "Type go and a code for a location/directory
echo For example
echo go D
echo will change disks (D:)
echo go home
echo will change directories to the users home directory (%homepath%)
echo go pictures
echo will change directories to %homepath%\pictures
echo Notes
echo @ sigh prevents echo on the current command
echo The echo on/off turns on/off the echo command. Turn on for debugging
echo Paths (only) with folder names with spaces need to be inclosed in         quotes (not the ommand)
goto :done

:docs
echo executing "%homedrive%%homepath%\Documents"
%homedrive%
cd "%homepath%\Documents"\test error\
if %errorlevel% neq 0 goto :error
goto :done

:error
echo Error: Input (%1 %2 %3 %4 %5 %6 %7 %8 %9) or command is invalid
echo go help for help
goto :done

:done

มีเหตุผลสำหรับcd's /dสวิทช์: cd /d "C:\Users\Me" (and the proper path delimeter for Windows is `ไม่ได้/)
เตฟาน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.