ใน Windows คุณเข้าถึงอาร์กิวเมนต์ที่ส่งผ่านเมื่อเรียกใช้ไฟล์แบตช์ได้อย่างไร
hello.bat
ตัวอย่างเช่นสมมติว่าผมมีโปรแกรมที่ชื่อว่า เมื่อฉันป้อนhello -a
ที่บรรทัดคำสั่งของ Windows ฉันจะให้โปรแกรมของฉันรู้ว่า-a
มันถูกส่งเป็นอาร์กิวเมนต์ได้อย่างไร
ใน Windows คุณเข้าถึงอาร์กิวเมนต์ที่ส่งผ่านเมื่อเรียกใช้ไฟล์แบตช์ได้อย่างไร
hello.bat
ตัวอย่างเช่นสมมติว่าผมมีโปรแกรมที่ชื่อว่า เมื่อฉันป้อนhello -a
ที่บรรทัดคำสั่งของ Windows ฉันจะให้โปรแกรมของฉันรู้ว่า-a
มันถูกส่งเป็นอาร์กิวเมนต์ได้อย่างไร
คำตอบ:
เป็นคนอื่นได้แล้วกล่าวว่าพารามิเตอร์ผ่านบรรทัดคำสั่งที่สามารถเข้าถึงได้ในไฟล์ชุดที่มีสัญกรณ์ไป%1
%9
นอกจากนี้ยังมีโทเค็นอื่นอีกสองตัวที่คุณสามารถใช้ได้:
%0
เป็นปฏิบัติการ (ไฟล์ batch) ชื่อตามที่ระบุไว้ในบรรทัดคำสั่ง%*
เป็นพารามิเตอร์ทั้งหมดที่ระบุในบรรทัดคำสั่ง - ซึ่งมีประโยชน์มากหากคุณต้องการส่งต่อพารามิเตอร์ไปยังโปรแกรมอื่นนอกจากนี้ยังมีเทคนิคที่สำคัญมากมายที่ต้องระวังนอกเหนือจากวิธีการเข้าถึงพารามิเตอร์
สิ่งนี้ทำกับโครงสร้างอย่างเช่นIF "%~1"==""
ซึ่งเป็นจริงถ้าหากไม่มีการโต้แย้งใด ๆ เลย หมายเหตุตัวละครตัวหนอนซึ่งทำให้คำพูดโดยรอบใด ๆ ที่จะถูกลบออกจากค่าของ%1
; หากไม่มีเครื่องหมายตัวหนอนคุณจะได้รับผลลัพธ์ที่ไม่คาดคิดหากค่านั้นมีเครื่องหมายคำพูดคู่รวมถึงความเป็นไปได้ของข้อผิดพลาดทางไวยากรณ์
หากคุณจำเป็นต้องเข้าถึงมากกว่า 9 SHIFT
ข้อโต้แย้งที่คุณต้องใช้คำสั่ง คำสั่งนี้จะเปลี่ยนแปลงค่าของการขัดแย้งทุกสถานที่หนึ่งเพื่อที่%0
จะใช้เวลาค่าของ%1
, %1
ใช้เวลาค่าของ%2
ฯลฯ%9
ใช้เวลาคุ้มค่าของการโต้แย้งที่สิบ (ถ้าเป็นปัจจุบัน) ซึ่งไม่สามารถใช้ได้ผ่านตัวแปรใด ๆ ก่อนที่จะเรียกSHIFT
(ป้อน คำสั่งSHIFT /?
สำหรับตัวเลือกเพิ่มเติม)
SHIFT
ยังมีประโยชน์เมื่อคุณต้องการประมวลผลพารามิเตอร์โดยไม่ต้องการให้แสดงตามลำดับที่ต้องการ ยกตัวอย่างเช่นสคริปต์อาจรู้จักธง-a
และ-b
ในลำดับใด วิธีที่ดีในการแยกวิเคราะห์บรรทัดคำสั่งในกรณีเช่นนี้คือ
:parse
IF "%~1"=="" GOTO endparse
IF "%~1"=="-a" REM do something
IF "%~1"=="-b" REM do something else
SHIFT
GOTO parse
:endparse
REM ready for action!
ชุดรูปแบบนี้ช่วยให้คุณแยกวิเคราะห์บรรทัดคำสั่งที่ซับซ้อนโดยไม่ต้องบ้า
สำหรับพารามิเตอร์ที่แสดงชื่อไฟล์เชลล์มีฟังก์ชันที่เกี่ยวข้องกับการทำงานกับไฟล์ที่ไม่สามารถเข้าถึงได้ในวิธีอื่น %~
ฟังก์ชั่นนี้จะเข้าถึงได้ด้วยโครงสร้างที่ขึ้นต้นด้วย
ตัวอย่างเช่นในการรับขนาดของไฟล์ที่ส่งผ่านเป็นการใช้อาร์กิวเมนต์
ECHO %~z1
ในการรับพา ธ ของไดเรกทอรีที่เปิดไฟล์แบตช์ (มีประโยชน์มาก!) คุณสามารถใช้ได้
ECHO %~dp0
คุณสามารถดูความสามารถทั้งหมดได้โดยการพิมพ์CALL /?
ที่ command prompt
"name=John"
จะกลายเป็นname John
ในช่วง exe วิธีหลีกเลี่ยงปัญหาคือล้อมรอบด้วยเครื่องหมายคำพูดเดี่ยว'"name=John"'
CALL /?
แค่ไหนแล้ว! ที่นี่ฉันชนกับ Google ตลอดเวลา
การใช้พารามิเตอร์ในแบตช์ไฟล์:% 0 และ% 9
ไฟล์ batch สามารถอ้างถึงคำพูดที่ส่งผ่านเป็นพารามิเตอร์ที่มีสัญญาณ: ไป%0
%9
%0 is the program name as it was called.
%1 is the first command line parameter
%2 is the second command line parameter
and so on till %9.
พารามิเตอร์ที่ส่งเข้ามาใน commandline จะต้องเป็นตัวอักษรและตัวเลขและคั่นด้วยช่องว่าง เนื่องจาก%0
เป็นชื่อโปรแกรมตามที่ถูกเรียกใน DOS %0
จะว่างเปล่าสำหรับ AUTOEXEC.BAT หากเริ่มต้นในเวลาบูต
ตัวอย่าง:
วางคำสั่งต่อไปนี้ในไฟล์แบทช์ชื่อmybatch.bat
:
@echo off
@echo hello %1 %2
pause
เรียกใช้ไฟล์แบตช์ดังนี้: mybatch john billy
จะแสดงผล:
hello john billy
รับพารามิเตอร์มากกว่า 9 รายการสำหรับไฟล์แบตช์ใช้:% *
โทเค็น Percent Star %*
หมายถึง "พารามิเตอร์ที่เหลือ" คุณสามารถใช้ห่วงสำหรับเพื่อคว้าพวกเขาตามที่กำหนดไว้ที่นี่:
http://www.robvanderwoude.com/parameters.php
หมายเหตุเกี่ยวกับตัวคั่นสำหรับพารามิเตอร์แบตช์
อักขระบางตัวในพารามิเตอร์บรรทัดคำสั่งจะถูกละเว้นโดยแบตช์ไฟล์ขึ้นอยู่กับรุ่นของ DOS ไม่ว่าจะเป็น "Escape" หรือไม่และมักขึ้นอยู่กับตำแหน่งในบรรทัดคำสั่ง:
commas (",") are replaced by spaces, unless they are part of a string in
double quotes
semicolons (";") are replaced by spaces, unless they are part of a string in
double quotes
"=" characters are sometimes replaced by spaces, not if they are part of a
string in double quotes
the first forward slash ("/") is replaced by a space only if it immediately
follows the command, without a leading space
multiple spaces are replaced by a single space, unless they are part of a
string in double quotes
tabs are replaced by a single space
leading spaces before the first command line argument are ignored
ไฟล์แบทช์ส่งข้อความโดยอัตโนมัติหลังจากโปรแกรมตราบใดที่พวกเขาเป็นตัวแปรในการกำหนดให้ พวกเขาจะถูกส่งผ่านตามลำดับพวกเขาจะถูกส่ง; เช่น% 1 จะเป็นสตริงแรกที่ส่งหลังจากเรียกใช้โปรแกรมเป็นต้น
หากคุณมี Hello.bat และเนื้อหาคือ:
@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause
และคุณเรียกใช้แบทช์ในคำสั่งผ่าน
hello.bat APerson241% วันที่%
คุณควรได้รับข้อความนี้กลับมา:
สวัสดี APerson241 ขอบคุณที่ใช้งานไฟล์แบตช์นี้ (01/11/2013)
@ Jon's :parse
/ :endparse
แบบแผนเป็นการเริ่มต้นที่ยอดเยี่ยมและเขามีความกตัญญูต่อการเริ่มต้นครั้งแรก แต่ถ้าคุณคิดว่าระบบแบตช์ของ Windows จะทำให้คุณตกใจง่าย…เอ่อเพื่อนคุณกำลังตกใจ ฉันใช้เวลาตลอดทั้งวันกับปีศาจนี้และหลังจากการวิจัยและการทดลองที่เจ็บปวดมากในที่สุดฉันก็จัดการบางสิ่งบางอย่างที่เป็นประโยชน์สำหรับยูทิลิตี้ในชีวิตจริง
foobar
ให้เราบอกว่าเราต้องการที่จะใช้ยูทิลิตี้ มันต้องมีคำสั่งเริ่มต้น มันมีพารามิเตอร์ทางเลือก--foo
ซึ่งรับค่าตัวเลือก (ซึ่งไม่สามารถเป็นพารามิเตอร์อื่นได้) default
ถ้าค่าจะหายไปค่าเริ่มต้นของมัน นอกจากนี้ยังมีพารามิเตอร์ตัวเลือก--bar
ที่จะใช้เวลาที่ต้องการความคุ้มค่า สุดท้ายสามารถใช้แฟลก--baz
โดยไม่อนุญาตให้มีค่า โอ้และพารามิเตอร์เหล่านี้สามารถมาในลำดับใดก็ได้
กล่าวอีกนัยหนึ่งดูเหมือนว่า:
foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]
ซับซ้อน? ไม่ดูเหมือนเป็นเรื่องปกติของสาธารณูปโภคในชีวิตจริง ( git
ใคร?)
หากไม่มีความกังวลใจต่อไปนี้เป็นวิธีแก้ปัญหา:
@ECHO OFF
SETLOCAL
REM FooBar parameter demo
REM By Garret Wilson
SET CMD=%~1
IF "%CMD%" == "" (
GOTO usage
)
SET FOO=
SET DEFAULT_FOO=default
SET BAR=
SET BAZ=
SHIFT
:args
SET PARAM=%~1
SET ARG=%~2
IF "%PARAM%" == "--foo" (
SHIFT
IF NOT "%ARG%" == "" (
IF NOT "%ARG:~0,2%" == "--" (
SET FOO=%ARG%
SHIFT
) ELSE (
SET FOO=%DEFAULT_FOO%
)
) ELSE (
SET FOO=%DEFAULT_FOO%
)
) ELSE IF "%PARAM%" == "--bar" (
SHIFT
IF NOT "%ARG%" == "" (
SET BAR=%ARG%
SHIFT
) ELSE (
ECHO Missing bar value. 1>&2
ECHO:
GOTO usage
)
) ELSE IF "%PARAM%" == "--baz" (
SHIFT
SET BAZ=true
) ELSE IF "%PARAM%" == "" (
GOTO endargs
) ELSE (
ECHO Unrecognized option %1. 1>&2
ECHO:
GOTO usage
)
GOTO args
:endargs
ECHO Command: %CMD%
IF NOT "%FOO%" == "" (
ECHO Foo: %FOO%
)
IF NOT "%BAR%" == "" (
ECHO Bar: %BAR%
)
IF "%BAZ%" == "true" (
ECHO Baz
)
REM TODO do something with FOO, BAR, and/or BAZ
GOTO :eof
:usage
ECHO FooBar
ECHO Usage: foobar ^<command^> [--foo [^<fooval^>]] [--bar ^<barval^>] [--baz]
EXIT /B 1
ใช่มันเลวร้ายจริงๆ ดูโพสต์ที่คล้ายกันของฉันที่https://stackoverflow.com/a/50653047/421049ที่ฉันให้การวิเคราะห์เพิ่มเติมเกี่ยวกับสิ่งที่เกิดขึ้นในตรรกะและเหตุผลที่ฉันใช้โครงสร้างบางอย่าง
น่าเกลียด ส่วนใหญ่ฉันต้องเรียนรู้วันนี้ และมันก็เจ็บ
ใช้ตัวแปรคือ.BAT
ตัวแปรและเรียก%0
ใช้%9