เอกสารฉบับที่ 2 ที่ Peter Mortensen กล่าวถึงในความคิดเห็นของเขาเกี่ยวกับคำตอบของ Codesmith ทำให้สิ่งต่างๆชัดเจนขึ้นสำหรับฉัน เอกสารนั้นเขียนโดย windowsinspired.com การเชื่อมโยงซ้ำ: วิธีที่ดีกว่าการทำความเข้าใจและ Quoting หนีของข้อโต้แย้งของ
การลองผิดลองถูกเพิ่มเติมบางอย่างนำไปสู่แนวทางต่อไปนี้:
หลีกหนีทุกคำพูดคู่"ด้วยเครื่องหมายคาเร็^ต หากคุณต้องการตัวละครอื่น ๆ ที่มีความหมายเป็นพิเศษกับเปลือกคำสั่งของ Windows (เช่น<, >, |, &) ที่จะตีความว่าเป็นตัวละครปกติแทนแล้วหลบหนีพวกเขาด้วยเครื่องหมายมากเกินไป
หากคุณต้องการโปรแกรมของคุณfooจะได้รับข้อความบรรทัดคำสั่ง"a\"b c" > dและการเปลี่ยนเส้นทางการส่งออกไปยังแฟ้มout.txtแล้วเริ่มต้นโปรแกรมของคุณดังนี้จากเปลือกคำสั่งของ Windows:
foo ^"a\^"b c^" ^> d > out.txt
ถ้าfooตีความ\"เป็นราคาคู่ที่แท้จริงและคาดว่าราคาคู่ใช้ Escape ข้อโต้แย้งคั่นที่มีช่องว่างแล้วfooตีความคำสั่งตามที่ระบุหนึ่งอาร์กิวเมนต์a"b cหนึ่งอาร์กิวเมนต์และอาร์กิวเมนต์หนึ่ง>d
หากแทนfooตีความเครื่องหมายอัญประกาศคู่""เป็นเครื่องหมายคำพูดคู่ตามตัวอักษรให้เริ่มโปรแกรมของคุณเป็น
foo ^"a^"^"b c^" ^> d > out.txt
ข้อมูลเชิงลึกที่สำคัญจากเอกสารที่ยกมาคือสำหรับเชลล์คำสั่งของ Windows เครื่องหมายคำพูดคู่ที่ไม่ใช้ Escape จะเรียกการสลับระหว่างสองสถานะที่เป็นไปได้
การทดลองและข้อผิดพลาดเพิ่มเติมบางอย่างบ่งบอกว่าในสถานะเริ่มต้นระบบจะรับรู้การเปลี่ยนเส้นทาง (ไปยังไฟล์หรือไปป์) และเครื่องหมายคาเร็ตจะหลีกเลี่ยงเครื่องหมาย^คำพูดคู่และเครื่องหมายคาเร็ตจะถูกลบออกจากอินพุต ในอีกสถานะหนึ่งจะไม่รู้จักการเปลี่ยนเส้นทางและเครื่องหมายคาเร็ตจะไม่หนีเครื่องหมายอัญประกาศคู่และจะไม่ถูกลบออก ลองอ้างถึงสถานะเหล่านี้ว่า 'ภายนอก' และ 'ภายใน' ตามลำดับ
หากคุณต้องการเปลี่ยนทิศทางผลลัพธ์ของคำสั่งของคุณเชลล์คำสั่งจะต้องอยู่ในสถานะภายนอกเมื่อถึงการเปลี่ยนเส้นทางดังนั้นจึงต้องมีเครื่องหมายคำพูดคู่ที่ไม่ใช้ Escape (โดยคาเร็ต) จำนวนเท่ากันก่อนการเปลี่ยนเส้นทาง foo "a\"b " > out.txtจะไม่ทำงาน - เชลล์คำสั่งผ่านทั้ง"a\"b " > out.txtการfooเป็นอาร์กิวเมนต์บรรทัดคำสั่งรวมของมันแทนการส่งผ่านเพียง"a\"b "และเปลี่ยนเส้นทางออกไปout.txt
foo "a\^"b " > out.txtจะไม่ทำงานอย่างใดอย่างหนึ่งเพราะลูกศร^จะพบในรัฐภายในที่เป็นตัวอักษรธรรมดาและไม่ได้เป็นตัวหนีเพื่อให้"a\^"b " > out.txtได้รับการส่งผ่านไปยังfoo
วิธีเดียวที่ (หวังว่า) จะใช้ได้ผลเสมอคือให้เชลล์คำสั่งอยู่ในสถานะภายนอกเสมอเพราะการเปลี่ยนเส้นทางจะทำงาน
หากคุณไม่ต้องการการเปลี่ยนเส้นทาง (หรืออักขระอื่น ๆ ที่มีความหมายพิเศษสำหรับเชลล์คำสั่ง) คุณสามารถทำได้โดยไม่ต้องใช้คาเร็ต หากfooตีความ\"ว่าเป็นเครื่องหมายคำพูดคู่ตามตัวอักษรคุณสามารถเรียกมันว่า
foo "a\"b c"
จากนั้นfooรับเป็นข้อความข้อโต้แย้งรวมและสามารถตีความมันเป็นอาร์กิวเมนต์เดียวเท่ากับ"a\"b c"a"b c
ตอนนี้ - สุดท้าย - สำหรับคำถามเดิม myscript '"test"'เรียกจากเปลือกคำสั่งของ Windows ผ่าน'"test"'ไปMyScript เห็นได้ชัดว่าmyscriptตีความเครื่องหมายคำพูดเดี่ยวและคู่เป็นตัวคั่นอาร์กิวเมนต์และลบออก คุณต้องหาว่าmyscriptยอมรับอะไรเป็นเครื่องหมายคำพูดคู่ตามตัวอักษรจากนั้นระบุในคำสั่งของคุณโดยใช้^เพื่อหลีกเลี่ยงอักขระใด ๆ ที่มีความหมายพิเศษกับเชลล์คำสั่งของ Windows เนื่องจากmyscriptมีให้ใน Unix ด้วยอาจ\"จะเป็นเคล็ดลับ ลอง
myscript \^"test\^"
หรือหากคุณไม่ต้องการการเปลี่ยนเส้นทาง
myscript \"test\"
myscript \"test\"