ฉันจะตรวจสอบได้อย่างไรว่าอาร์กิวเมนต์ถูกกำหนดเมื่อเริ่มต้น / เรียกไฟล์แบตช์


99

ฉันพยายามใช้ตรรกะการตรวจสอบความถูกต้องต่อไปนี้ในไฟล์แบตช์ แต่บล็อก "การใช้งาน" จะไม่ดำเนินการแม้ว่าจะไม่มีพารามิเตอร์ให้กับไฟล์แบตช์ก็ตาม

if ("%1"=="") goto usage

@echo This should not execute

@echo Done.
goto :eof

:usage
@echo Usage: %0 <EnvironmentName>
exit 1

ผมทำอะไรผิดหรือเปล่า?



1
@ double-beep - คำถามที่นี่ (โดย daniel-fortunov) ถูกถามก่อนประมาณหนึ่งปีก่อนที่คำถามที่คุณอ้างถึงจะถูกโพสต์ ข้อใด (เป็นไปได้) ที่ซ้ำกัน
Kevin Fegan

1
@KevinFegan เพราะคำถามอื่นมีมุมมองและคำตอบมากขึ้น
เสียงบี๊บสองครั้ง

คำตอบ:


150

การตรวจสอบสำหรับชุดว่าอาร์กิวเมนต์ commandline ได้รับสามารถ[%1]==[]แต่เป็นเดฟคอส ชี้ให้เห็น , "%1"==""นอกจากนี้ยังจะทำงาน

ฉันยังแก้ไขข้อผิดพลาดทางไวยากรณ์ในเสียงสะท้อนการใช้งานเพื่อหลีกเลี่ยงสัญญาณที่มากกว่าและน้อยกว่า นอกจากนี้exitความต้องการการ/Bโต้เถียงมิฉะนั้นCMD.exeจะเลิก

@echo off

if [%1]==[] goto usage
@echo This should not execute
@echo Done.
goto :eof
:usage
@echo Usage: %0 ^<EnvironmentName^>
exit /B 1

19
[% 1] == [] ดีกว่า "% 1" == "" เพราะจะจัดการกรณีที่% 1 มีเครื่องหมายอัญประกาศคู่ได้อย่างถูกต้อง "% 1" == "" จะเกิดข้อผิดพลาดพร้อมข้อความ "ไม่คาดคิดในเวลานี้"
tekumara

2
โปรดทราบว่าหากคุณไม่ได้ใช้อาร์กิวเมนต์บรรทัดคำสั่ง แต่เป็นsetตัวแปร (ฉันไม่รู้คำศัพท์เฉพาะกลุ่มที่ถูกต้อง) คุณอาจต้องการใช้"%myvar%"==""เพราะหากmyvarมีช่องว่างอยู่และไม่ได้ยกมาคุณจะได้รับ "ไม่คาดคิดในเวลานี้ "ข้อความ.
พาท

1
@Pat SET ตัวแปรสามารถตรวจสอบได้ด้วยIF NOT DEFINED VarNameบล็อก นอกจากนี้ +1 ถึง tukushan ที่ไม่ใช้เครื่องหมายคำพูดในการเปรียบเทียบ เพียงแค่ไม่ทำมัน ไม่เลย
Fr0sT

11
"%~1"==""จะทำงานและดูแลกรณีที่% 1 มีเครื่องหมายคำพูดคู่
Drakkim

9
"%~1"==""จัดการช่องว่างในตัวแปรในขณะที่[]เวอร์ชันไม่มี
Cookie Butter

18

ตัวอย่างขั้นสูงเพิ่มเติม:

⍟ข้อโต้แย้งไม่ จำกัด

⍟มีอยู่ในระบบไฟล์ (อย่างใดอย่างหนึ่งfileหรือdirectory?) หรือไฟล์string.

⍟ระบุว่าเป็นไฟล์หรือไม่

⍟ระบุเป็นไดเร็กทอรี

ไม่มีส่วนขยายจะใช้งานได้ในสคริปต์ดั้งเดิม!

รหัสขั้นต่ำ☺

@echo ปิด

: ห่วง
      :: -------------------------- มีข้อโต้แย้ง?
      ถ้า ["% ~ 1"] == [""] (
        เสียงสะท้อนเสร็จสิ้น
        goto end
      )
      :: -------------------------- มีข้อโต้แย้ง?
      ถ้าไม่มีอยู่% ~ s1 (
        ไม่มีเสียงสะท้อน
      ) อื่น ๆ (
        เสียงสะท้อนอยู่
        ถ้ามีอยู่% ~ s1 \ NUL (
          echo คือไดเร็กทอรี
        ) อื่น ๆ (
          echo คือไฟล์
        )
      )
      :: --------------------------
      กะ
      โกโตลูป
      
      
: จบ

หยุด

✨ของอื่น ๆ .. ✨

■ใน%~1- ~ลบการห่อ"หรือ'.

■ใน%~s1- sทำให้เส้นทางเป็นDOS 8.3 namingซึ่งเป็นเคล็ดลับที่ดีในการหลีกเลี่ยงช่องว่างในชื่อไฟล์ขณะตรวจสอบสิ่งต่างๆ (และวิธีนี้ไม่จำเป็นต้องรวมทรัพยากรด้วย"s มากขึ้น

["%~1"]==[""]"ไม่สามารถแน่ใจได้" หากอาร์กิวเมนต์เป็นไฟล์ / ไดเร็กทอรีหรือเป็นเพียงสตริงทั่วไปดังนั้นนิพจน์จึงใช้วงเล็บและต้นฉบับที่ยังไม่ได้แก้ไขแทน%1(โดยไม่ต้องมีการ"ตัดหากมี .. )

ถ้ามีข้อโต้แย้งว่าถ้าเราได้ใช้ไม่มีและตัวชี้หาเรื่องรายการได้ผ่านช่วงหนึ่งการแสดงออกจะได้รับการประเมินเพื่อshift[""]==[""]

■นี่เป็นสิ่งที่เฉพาะเจาะจงมากที่สุดที่คุณสามารถทำได้โดยไม่ต้องใช้เทคนิคเพิ่มเติม (จะใช้ได้แม้ในชุดสคริปต์ของ windows-95 ... )

■ตัวอย่างการดำเนินการ

บันทึกเป็น identifier.cmd

สามารถระบุอาร์กิวเมนต์ได้ไม่ จำกัด (โดยปกติคุณ จำกัด ไว้ที่%1- %9) เพียงอย่าลืมปิดอาร์กิวเมนต์ด้วยเครื่องหมายจุลภาคกลับด้านหรือใช้การตั้งชื่อ 8.3 หรือลากและวางทับ (จะทำอย่างใดอย่างหนึ่งโดยอัตโนมัติ)


สิ่งนี้ช่วยให้คุณสามารถรันคำสั่งต่อไปนี้:

identifier.cmd c:\windows และจะได้รับ

มีอยู่
เป็นไดเร็กทอรี
เสร็จแล้ว

identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" และจะได้รับ

มีอยู่
เป็นไฟล์
เสร็จแล้ว

⓷และหลายข้อโต้แย้ง(แน่นอนว่านี่คือข้อตกลงทั้งหมด .. )

identifier.cmd c:\windows\system32 c:\hiberfil.sys "c:\pagefile.sys" hello-world

และจะได้รับ

มีอยู่
เป็นไดเร็กทอรี
มีอยู่
เป็นไฟล์
มีอยู่
เป็นไฟล์
ไม่มีอยู่จริง
เสร็จแล้ว

โดยธรรมชาติแล้วมันอาจซับซ้อนกว่านี้มาก แต่ตัวอย่างที่ดีควรเรียบง่ายและน้อยที่สุด :)

หวังว่าจะช่วยทุกคน :)

เผยแพร่ที่นี่: CMD Ninja - การประมวลผลอาร์กิวเมนต์แบบไม่ จำกัด การระบุว่ามีอยู่ในระบบไฟล์หรือไม่การระบุว่าไฟล์หรือไดเรกทอรี

และนี่คือตัวอย่างการทำงานที่ใช้ไฟล์ APK (แอป Android) จำนวนเท่าใดก็ได้และติดตั้งลงในอุปกรณ์ของคุณผ่านคอนโซลดีบัก (ADB.exe): สร้างโพสต์ก่อนหน้าตัวติดตั้ง APK จำนวนมากที่ไม่ใช้ ADB Install-Multi Syntax


14

กำจัดวงเล็บ

ไฟล์แบตช์ตัวอย่าง:

echo "%1"

if ("%1"=="") echo match1

if "%1"=="" echo match2

ผลลัพธ์จากการรันสคริปต์ด้านบน:

C:\>echo "" 
""

C:\>if ("" == "") echo match1 

C:\>if "" == "" echo match2 
match2

ฉันคิดว่ามันเป็นการเอาวงเล็บมาเป็นส่วนหนึ่งของสตริงและกำลังถูกเปรียบเทียบ


1
if "%1"==""จะผิดพลาดหากอาร์กิวเมนต์มีช่องว่าง ตัวอย่างเช่น: run.bat "a b". @amr มีคำตอบที่ดีที่สุดในการใช้if "%~1"==""
wisbucky

6
IF "%~1"=="" GOTO :Usage

~ จะยกเลิกการเสนอราคา% 1 ถ้า% 1 ถูกยกมา

"" จะป้องกันจากอักขระพิเศษที่ส่งผ่าน ตัวอย่างเช่นการเรียกสคริปต์ด้วย & ping


1
นี่คือคำตอบที่ดีที่สุด คำตอบอื่น ๆ ใช้ได้กับบางกรณี แต่จะล้มเหลวสำหรับกรณีพิเศษเช่นrun.bat "a b"
wisbucky

@wisbucky นั่นดูเหมือนจะไม่เลอะคำตอบที่ได้รับการยอมรับ ฉันขาดอะไรไป?
ruffin

@ruffin, Example: จะไม่ถูกจับโดยมีrun.bat "" [%1]==[]
wisbucky


2

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

@echo off
:: add other test for the arguments here...
if not [%1]==[] goto main
:: --------------------------
echo This command does something.
echo.
echo %0 param%%1 param%%2
echo       param%%1 the file to operate on
echo       param%%1 another file

:: --------------------------
exit /B 1

:main
:: --------------------------
echo do something with all arguments (%%* == %*) here...

อย่างไรก็ตามหากคุณไม่จำเป็นต้องใช้ cmd / batch ให้ใช้ bash บน WSL หรือ powershell พวกเขาจะมีไวยากรณ์ที่มีเหตุผลมากกว่าและคุณสมบัติที่มีความลึกลับน้อยกว่า


0

IF "% 1" == "" จะล้มเหลวทุกเวอร์ชันจะล้มเหลวภายใต้เงื่อนไขอักขระพิษบางประการ เฉพาะในกรณีที่ถูกกำหนดหรือหากไม่ถูกกำหนดเท่านั้นที่ปลอดภัย


if [not] defined ...ไม่ทำงานกับพารามิเตอร์เช่น%1. คุณมีตัวอย่างไหมที่ใช้if "%~1" ...ไม่ได้?
Stephan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.