การหลีกเลี่ยงเครื่องหมายคำพูดและเครื่องหมายคำพูดคู่


94

ฉันจะหลีกเลี่ยงเครื่องหมายคำพูดใน-paramค่าในบรรทัดคำสั่งต่อไปนี้ได้อย่างไร

$cmd="\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'""
Invoke-Expression $cmd 

เรื่องนี้ล้มเหลวแน่นอน ฉันพยายามหลีกเลี่ยงเครื่องหมายคำพูด (เดี่ยวและคู่) โดยใช้อักขระหนี `และทำการผสมหลายอย่าง แต่ไม่มีอะไรทำงาน


ดูเพิ่มเติมวิงวอนแสดงออกถือว่าเป็นอันตราย
Peter Mortensen

@PeterMortensen มีปัญหากับบทความนี้คือดูเหมือนจะไม่มีวิธีที่ดีกว่าเมื่อคุณต้องการเปิดแอปพลิเคชันเนทีฟและส่งผ่านพารามิเตอร์ที่มีเครื่องหมายคำพูดคู่เป็นอาร์กิวเมนต์
Andrew Savinykh

@Andrew Savinykh: วิธีหนึ่งคือการเปิดมันผ่าน cmd $someCommandStringWithDoubleQuotes | cmdแทน: สิ่งนี้ใช้งานได้จริงจากสคริปต์ PowerShell (เช่นการเรียกใช้CMake (ซึ่งต้องใช้เครื่องหมายอัญประกาศคู่ (มิฉะนั้นจะล้มเหลวโดยไม่โต้ตอบ))) อีกทางเลือกหนึ่งสำหรับ CMD คือ bash.exe ( MinGW ) - แต่การเริ่มต้นอาจช้ามากในบางสถานการณ์
Peter Mortensen

คำตอบ:


60

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

เรื่องสั้นขนาดยาว: คุณแค่พันสตริงด้วย @ '... ' @:

Start-Process \\server\toto.exe @'
-batch=B -param="sort1;parmtxt='Security ID=1234'"
'@

(โปรดจำไว้ว่าฉันคิดว่าคำพูดใดที่จำเป็นและสิ่งที่คุณพยายามหลีกเลี่ยง) หากคุณต้องการทำงานกับผลลัพธ์คุณอาจต้องเพิ่ม-NoNewWindowสวิตช์

BTW: นี่เป็นปัญหาที่สำคัญมากเนื่องจาก v3 คุณสามารถใช้--%เพื่อหยุดตัวแยกวิเคราะห์ PowerShell ไม่ให้ทำอะไรกับพารามิเตอร์ของคุณ:

\\server\toto.exe --% -batch=b -param="sort1;paramtxt='Security ID=1234'"

... ควรทำงานได้ดีที่นั่น (ด้วยสมมติฐานเดียวกัน)


ขอบคุณสำหรับคำตอบ เริ่มต้นกระบวนการไม่ว่าฉันจะพยายามบ่นเสมอ ดังนั้นฉันจึง cmd / C $ cmd (โดยที่ $ cmd เป็นคำสั่งทั้งหมดของฉันรวมถึง. exe) ฉันใช้ powershell 2.0 แม้แต่สตริงที่นี่ก็ใช้ไม่ได้ถ้าฉันจำไม่ผิด
eetawil

3
ดูเหมือนจะซับซ้อนโดยไม่จำเป็นเมื่อเทียบกับการใช้ backtick (`) เพื่อหลีกเลี่ยงเครื่องหมายคำพูดคู่
saille

6
วิธีนี้ใช้ได้ผลดีตราบเท่าที่คุณปฏิบัติตามกฎที่คาดไว้ @ แรกต้องอยู่ใน "บรรทัด 1" พารามิเตอร์ของคุณต้องอยู่ใน "บรรทัดที่ 2" และต้องลงท้าย "@" ใน "บรรทัดที่ 3" ตอนจบ "@ ต้องไม่มีช่องว่างข้างหน้า ผู้ชายไวยากรณ์นี้จู้จี้จุกจิก!
Ian Newland

ใช้งานได้ดี! หากคุณต้องการขยายตัวแปรในสตริงของคุณคุณสามารถใช้@"และ"@แทนได้
คิ้ว

97

การใช้ backtick (`) ใช้ได้ผลดีสำหรับฉันถ้าฉันวางไว้ในตำแหน่งต่อไปนี้:

$cmd="\\server\toto.exe -batch=B -param=`"sort1;parmtxt='Security ID=1234'`""

$cmd ส่งคืนเป็น:

\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'"

นั่นคือสิ่งที่คุณกำลังมองหาใช่ไหม

ข้อผิดพลาด PowerShell ทำให้ฉันอ้างถึงโทเค็นที่ไม่คาดคิด 'sort1' และนั่นคือวิธีที่ฉันกำหนดตำแหน่งที่จะใส่ backticks

ไวยากรณ์ @ '... ' @ เรียกว่า "สตริงที่นี่" และจะส่งกลับสิ่งที่ป้อน คุณยังสามารถใช้เพื่อเติมข้อมูลตัวแปรในลักษณะต่อไปนี้:

$cmd=@'
"\\server\toto.exe -batch=B -param="sort1;parmtxt='Security ID=1234'""
'@

สัญลักษณ์เปิดและปิดต้องอยู่ในบรรทัดของตัวเองดังที่แสดงด้านบน


ขออภัยในความล่าช้า ... วิธีที่ฉันทำให้มันได้ผลคือสุดท้ายเรียก cmd / C "MYCOMMAND" จาก powershell มันไม่ทำงานโดยใช้ powershell โดยตรง
eetawil

1
แต่ไม่Invoke-Expressionตัดเครื่องหมายคำพูดคู่$cmdเมื่อถูกเรียกใช้? หรือใช้$cmdโดยไม่ใช้Invoke-Expressionอย่างไร?
ปีเตอร์มอร์เทนเซน

8

วันนี้ฉันพบว่าตัวเองอยู่ในสถานการณ์ที่คล้ายกันขณะพยายามเรียกใช้คำสั่งผ่านโมดูล Node.js:

ฉันใช้ PowerShell และพยายามเรียกใช้:

command -e 'func($a)'

แต่ด้วยสัญลักษณ์พิเศษ PowerShell กำลังยุ่งเหยิงข้อโต้แย้ง ในการแก้ไขฉันกลับขีดฆ่าเครื่องหมายอัญประกาศคู่:

command -e `"func($a)`"

2
น่าสนใจ: ได้"['`"][^'`"]['`"]"ผล ... แต่'[`'"][^`'"][`'"]'ไม่! กำลังทำให้ฉันคลั่งไคล้
David J
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.