อะไรคือนิสัยที่ดีในการออกแบบอาร์กิวเมนต์บรรทัดคำสั่ง


190

ขณะพัฒนาแอปพลิเคชันฉันเริ่มสงสัย - ฉันควรออกแบบอาร์กิวเมนต์บรรทัดคำสั่งได้อย่างไร

จำนวนมากของโปรแกรมที่ใช้สูตรเช่นนี้หรือ-argument value วิธีการแก้ปัญหาที่เข้ามาอยู่ในใจของผมก็คือ/argument value argument:valueฉันคิดว่ามันดีเพราะไม่มีช่องว่างสีขาวไม่มีทางที่ค่าและการขัดแย้งสามารถทำให้ยุ่งเหยิงได้ นอกจากนี้ยังเป็นการง่ายที่จะแยกสตริงออกเป็นสอง:อักขระจากอักขระตัวแรกทางซ้าย

คำถามของฉันคือ:

  1. -argument valueสูตรยอดนิยมนั้นดีกว่าargument:value(อ่านง่ายขึ้นเขียนง่ายขึ้นไร้ข้อผิดพลาดเข้าใจง่ายขึ้นโดยนักพัฒนาผู้เชี่ยวชาญ) หรือไม่
  2. มีกฎที่รู้จักกันทั่วไปซึ่งฉันควรปฏิบัติตามในขณะที่ออกแบบอาร์กิวเมนต์บรรทัดคำสั่ง (นอกเหนือจากถ้ามันทำงานมันเป็น OK)?

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

เรากำลังทำงานกับแอปพลิเคชั่นที่จะใช้ในสถานที่สาธารณะ (touch totems, table) แอปพลิเคชันเขียนโดยใช้ Qt Quick 5 (C ++, QML, JS) อุปกรณ์จะติดตั้ง Windows 8.1 / 10 เราจะให้ส่วนต่อประสานส่วนหน้าเพื่อจัดการอุปกรณ์ อย่างไรก็ตามผู้ดูแลระบบขั้นสูงบางรายอาจต้องการกำหนดค่าแอปพลิเคชันด้วยตนเอง มันไม่สำคัญมากนักจากธุรกิจ แต่เป็นเพราะฉันเห็นด้วยกับสิ่งที่Kilian Fothบอกว่าฉันไม่ต้องการให้ใบสมัครของฉันเจ็บปวดสำหรับผู้ใช้ ไม่พบในอินเทอร์เน็ตสิ่งที่ฉันต้องการฉันถามที่นี่


สำหรับผู้ใช้ Stack Exchange ขั้นสูง: ฉันต้องการให้คำถามนี้เป็นเรื่องทั่วไป บางทีอาจมีคุณสมบัติเป็น wiki ของชุมชน (ฉันไม่ทราบว่าคำถามที่มีอยู่สามารถแปลงเป็นคำตอบได้หรือไม่) เนื่องจากฉันต้องการให้คำถามนี้เป็นระบบปฏิบัติการและภาษาการเขียนโปรแกรมอิสระคำตอบที่ปรากฏที่นี่อาจเป็นบทเรียนที่มีค่าสำหรับผู้พัฒนารายอื่น


14
ดูที่เครื่องมือบรรทัดคำสั่งยอดนิยม ตัวอย่างเช่นยัติภังค์เดียวมักจะใช้เพื่อให้ตัวเลือกการรวม เช่นคุณอาจจะเขียนls -ltrจะรวมตัวเลือก-l, และ-t -rโปรแกรมสไตล์ GNU ยังมักจะช่วยให้ตัวเลือกคำที่ใช้กับยัติภังค์คู่เหมือนแทน--reverse -rมีการประชุมยอดนิยมอื่น ๆ ที่ต้องการ-hแสดงความช่วยเหลือ--เพื่อส่งสัญญาณในตอนท้ายของตัวเลือกโดยระบุ-เป็นชื่อไฟล์ที่อนุญาตให้อ่านจาก stdin ฯลฯ
Brandin

72
ทั้ง-argument valueไม่ได้-argument:valueเป็นเรื่องธรรมดา ส่วนใหญ่จะเป็น-a value, และ-avalue --argument=value
reinierpost

39
ใช้ไลบรารีการแยกบรรทัดคำสั่งยอดนิยม (โดยปกติจะเรียกว่าคล้ายgetopt(s)) ที่คุณสามารถทำได้
reinierpost

5
@ k3b เรากำลังทำงานกับ Qt ตามที่เควินไคลน์กล่าวในความคิดเห็นของเขาเราสามารถใช้ห้องสมุดที่มีอยู่แล้ว ฉันคิดว่ามันเป็นหลายแพลตฟอร์มและคิดดี QCommandLineParser
Filip Hazubski

11
ปัญหาของการแจ้งเตือนครั้งสุดท้ายของคุณคือการแยกวิเคราะห์อาร์กิวเมนต์ไม่ใช่ปัญหาของแพลตฟอร์ม
pydsigner

คำตอบ:


237

สำหรับระบบ POSIX (เช่น Linux, MacOSX) อย่างน้อยสำหรับโปรแกรมที่อาจเริ่มต้นในเชลล์เทอร์มินัล (เช่นส่วนใหญ่) ฉันขอแนะนำให้ใช้วิธีการเข้ารหัส GNU (ซึ่งแสดงรายการชื่ออาร์กิวเมนต์ทั่วไป) และดูแนวทาง POSIX ยูทิลิตี้แม้สำหรับซอฟต์แวร์ที่เป็นกรรมสิทธิ์:

  • จัดการได้เสมอ--versionและ--help ( /bin/trueยอมรับได้ !!) ฉันสาปแช่งผู้เขียนซอฟต์แวร์ที่ไม่เข้าใจ--helpฉันเกลียดพวกเขา (เพราะprog --help เป็นคำสั่งแรกที่ฉันลองใช้ในโปรแกรมใหม่)! บ่อยครั้งที่--helpสามารถย่อเป็น-h

  • มี--helpรายการข้อความตัวเลือกทั้งหมด (ยกเว้นกรณีที่คุณมีมากเกินไปของพวกเขา ... ในรายการกรณีที่คนส่วนใหญ่และชัดเจนหมายถึงบางmanหน้าหรือ URL บางส่วน) และค่าเริ่มต้นของตัวเลือกและบางทีอาจจะสำคัญ (และโปรแกรมเฉพาะ ) ตัวแปรสภาพแวดล้อม แสดงรายการตัวเลือกเหล่านี้เกี่ยวกับข้อผิดพลาดอาร์กิวเมนต์ตัวเลือก

  • ยอมรับ-aข้อโต้แย้งสั้น ๆ (ตัวอักษรเดียว) และมีความเทียบเท่าบาง--long-argumentดังนั้น-a2 --long-argument=2, --long-argument 2; แน่นอนว่าคุณสามารถมี--only-long-argumentชื่อบางชื่อ(สำหรับตัวเลือกที่ไม่ค่อยได้ใช้) สำหรับข้อโต้แย้งแบบกิริยาที่ไม่มีตัวเลือกพิเศษ-cfมักได้รับการจัดการในฐานะ-c -fฯลฯ ดังนั้น-argument:valueข้อเสนอของคุณแปลกและฉันไม่แนะนำให้ทำเช่นนั้น

  • ใช้ GLIBC getopt_longหรือดีกว่า (เช่นargp_parseใน OCaml เป็นArgโมดูล , ... )

  • มักใช้-สำหรับอินพุตหรือเอาต์พุตมาตรฐาน (หากคุณไม่สามารถทำได้ให้จัดการ/dev/stdin& /dev/stdoutแม้แต่ในระบบปฏิบัติการบางระบบที่ไม่มีพวกเขา)

  • เลียนแบบพฤติกรรมของโปรแกรมที่คล้ายกันโดยการนำข้อเสนอทางเลือกส่วนใหญ่กลับมาใช้ซ้ำ โดยเฉพาะอย่างยิ่ง-nสำหรับ dry run (à la make), -hเพื่อขอความช่วยเหลือ, -vสำหรับ verbosity, ฯลฯ ...

  • ใช้--เป็นตัวคั่นระหว่างตัวเลือก & ไฟล์หรืออาร์กิวเมนต์อื่น ๆ

  • หากโปรแกรมของคุณใช้isattyทดสอบมากกว่าstdinคือเทอร์มินัล (และทำงานเป็น "แบบโต้ตอบ" ในกรณีนั้น) ให้ตัวเลือกในการบังคับใช้โหมดที่ไม่มีการโต้ตอบเช่นกันถ้าโปรแกรมของคุณมีอินเทอร์เฟซ GUI (และการทดสอบgetenv("DISPLAY")บนเดสก์ท็อป X11) นำมาใช้ในชุดหรือบรรทัดคำสั่ง

  • บางโปรแกรม (เช่นgcc) ยอมรับรายการอาร์กิวเมนต์ทางอ้อมดังนั้นจึง@somefile.txtมีความหมายว่าอ่านอาร์กิวเมนต์ของโปรแกรมจากsomefile.txt; สิ่งนี้อาจมีประโยชน์เมื่อโปรแกรมของคุณอาจยอมรับข้อโต้แย้งจำนวนมาก (มากกว่าเคอร์เนลของคุณARG_MAX)

BTW คุณอาจเพิ่มสิ่งอำนวยความสะดวกที่สมบูรณ์แบบอัตโนมัติสำหรับโปรแกรมและเชลล์ทั่วไป (เช่นbashหรือzsh)

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

ถ้าซอฟต์แวร์ของคุณเป็นชุดของโปรแกรมบรรทัดคำสั่งที่เกี่ยวข้องกับการใช้แรงบันดาลใจจากคอมไพล์ (ซึ่งคุณก็ใช้เป็นเครื่องมือในการพัฒนา) ซึ่งยอมรับgit helpและgit --helpมีจำนวนมากgitsubcommandและgitsubcommand--help

ในบางกรณีคุณอาจใช้argv[0](โดยใช้ symlink ในโปรแกรมของคุณ) เช่นbashเรียกใช้เช่นเดียวกับที่rbashมีพฤติกรรมที่แตกต่าง ( เชลล์จำกัด ) แต่ฉันมักจะไม่แนะนำให้ทำเช่นนั้น; มันอาจจะทำให้รู้สึกว่าโปรแกรมของคุณสามารถใช้เป็นล่ามสคริปต์ใช้shebangคือ#!ในบรรทัดแรกตีความโดยexecve (2) หากคุณทำอุบายเช่นนี้ต้องแน่ใจว่าเอกสารเหล่านั้นรวมถึงใน--helpข้อความ

โปรดจำไว้ว่าใน POSIX เปลือกเป็นglobbingข้อโต้แย้ง ( ก่อนที่จะเรียกใช้โปรแกรมของคุณ) เพื่อหลีกเลี่ยงการกำหนดตัวอักษร (ชอบ*หรือ$หรือ~) ในตัวเลือกที่จะต้องมีเปลือกหนี

ในบางกรณีคุณสามารถฝังล่ามเช่นGNU guileหรือLuaในซอฟต์แวร์ของคุณ (หลีกเลี่ยงการประดิษฐ์ภาษาสคริปต์ทัวริงของคุณเองหากคุณไม่เชี่ยวชาญในภาษาโปรแกรม) สิ่งนี้มีผลกระทบในเชิงลึกต่อการออกแบบซอฟต์แวร์ของคุณ (ควรให้ความสนใจก่อน!) จากนั้นคุณควรสามารถส่งสคริปต์หรือนิพจน์บางอย่างไปยังล่ามนั้นได้อย่างง่ายดาย หากคุณใช้วิธีการที่น่าสนใจออกแบบซอฟต์แวร์ของคุณและตีความดั้งเดิมด้วยความระมัดระวัง คุณอาจมีผู้ใช้รหัสแปลก ๆ เขียนสคริปต์ขนาดใหญ่สำหรับสิ่งที่คุณ

ในกรณีอื่น ๆ คุณอาจต้องการให้ผู้ใช้ขั้นสูงโหลดปลั๊กอินลงในซอฟต์แวร์ของคุณ (โดยใช้เทคนิคการโหลดแบบไดนามิก à la dlopen& dlsym) นี่เป็นการตัดสินใจออกแบบที่สำคัญมาก (ดังนั้นให้กำหนดและจัดทำเอกสารส่วนต่อประสานปลั๊กอินด้วยความระมัดระวัง) และคุณจะต้องกำหนดการประชุมเพื่อส่งตัวเลือกโปรแกรมไปยังปลั๊กอินเหล่านี้

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


ขอให้สังเกตว่า/optionเป็นสิ่งที่ Windows หรือ VMS มันจะเสียสติในระบบ POSIX (เพราะลำดับชั้นของไฟล์ใช้/เป็นตัวคั่นไดเรกทอรีและเพราะเชลล์ทำแบบกลม) คำตอบทั้งหมดของฉันส่วนใหญ่สำหรับ Linux (และ POSIX)


PS ถ้าเป็นไปได้ทำให้โปรแกรมของคุณเป็นซอฟต์แวร์ฟรีคุณจะได้รับการปรับปรุงจากผู้ใช้บางคนและนักพัฒนา (และการเพิ่มตัวเลือกโปรแกรมใหม่มักเป็นหนึ่งในสิ่งที่ง่ายที่สุดในการเพิ่มซอฟต์แวร์ฟรีที่มีอยู่) นอกจากนี้คำถามของคุณขึ้นอยู่เป็นจำนวนมากกับผู้ชมที่ตั้งใจไว้ : เกมสำหรับวัยรุ่นหรือเบราว์เซอร์สำหรับยายอาจไม่จำเป็นต้องมีชนิดเดียวกันและปริมาณของตัวเลือกกว่าคอมไพเลอร์หรือผู้ตรวจสอบเครือข่ายสำหรับการ sysadmins ดาต้าเซ็นเตอร์หรือซอฟต์แวร์ CAD สำหรับไมโครโปรเซสเซอร์ สถาปนิกหรือนักออกแบบสะพาน วิศวกรที่คุ้นเคยกับการเขียนโปรแกรมและการเขียนสคริปต์อาจชอบตัวเลือกที่ปรับได้มากกว่าคุณยายและอาจต้องการให้สามารถเรียกใช้แอปพลิเคชันของคุณได้โดยไม่ต้องใช้ X11 (อาจเป็นcrontabงาน)


18
เห็นด้วย แต่git เป็นตัวอย่างที่ดีกว่า ฉันจะไม่แนะนำแม้มองเข้าไปcvsในปี 2016
Basile Starynkevitch

8
+ ในกรณีที่ตัวเลือกที่ไม่ถูกต้องเพียงแสดงความช่วยเหลือ มันน่ารำคาญ SOOOO dd -hที่จะได้รับข้อผิดพลาดไร้ประโยชน์สำหรับตัวอย่างสำหรับ
domen

8
โปรแกรม GNU รองรับ--helpตามกฎ แต่มักจะไม่รับรู้-hว่าอะไรน่ารำคาญ ฉันมักจะพิมพ์ -h --helpเมื่อฉันเลือกที่จะลืมโปรแกรมก็เป็นที่น่ารำคาญที่จะต้องพิมพ์คำสั่งที่มีตัวเลือกอีกต่อไป หลังจากทั้งหมดฉันพิมพ์ -h เพราะฉันลืมบางสิ่งบางอย่าง เหตุใดผู้ใช้ควรได้รับการคาดหวังให้จำโปรแกรมที่ต้องการ '--help' และโปรแกรมใดที่ต้องใช้ '-h' เพื่อแสดงหน้าจอความช่วยเหลือ เพียงแค่มีตัวเลือกสำหรับทั้ง -h และ - ช่วย
Brandin

30
ส่วนแรกของคำตอบนี้ดี แต่ก็มีที่ไหนสักแห่งตามคุณไปสัมผัสแทนเจนต์ ตัวอย่างเช่นไฟล์กำหนดค่าปลั๊กอินและ dlopen ตัวเลือกสิทธิ์การใช้งานซอฟต์แวร์และเว็บเบราว์เซอร์ไม่เกี่ยวข้องกับข้อกำหนดของอินเตอร์เฟสบรรทัดคำสั่งอีกต่อไป
Brandin

5
และได้โปรด หากคุณฟอร์แมตเอาต์พุตสำหรับหน้าจอให้เพิ่มการแทนที่รูปแบบเอาต์พุต ไม่มีอะไรทำให้ฉันรำคาญมากกว่าคำสั่งที่ตัดหรือตัดบรรทัดเมื่อฉันพยายามใช้ในสคริปต์
Sobrique

68

ความจริงที่ว่าการประชุมรูปแบบข้อมูลเป็นที่นิยมนั้นเป็นข้อได้เปรียบ

คุณสามารถเห็นได้อย่างง่ายดายว่าการใช้ = หรือ: หรือแม้กระทั่ง '' เป็นตัวคั่นเป็นความแตกต่างเล็กน้อยที่สามารถแปลงเป็นคอมพิวเตอร์โดยใช้ความพยายามเล็กน้อย สิ่งที่จะเป็นความพยายามครั้งยิ่งใหญ่สำหรับมนุษย์ที่จะจำได้ว่า "ทีนี้ดูสิโปรแกรมที่ใช้งานไม่บ่อยครั้งนี้จะกำหนดสิ่งต่าง ๆ ด้วย:หรือ=ไม่? อืม ... "

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


19
สำหรับเกือบทุกภาษามีฟังก์ชั่นห้องสมุดเพื่อจัดการกับอาร์กิวเมนต์บรรทัดคำสั่ง ใช้หนึ่งในนั้น
วินไคลน์

9
คำแนะนำที่ดี แต่อนุสัญญาเหล่านั้นคืออะไร? -1
RubberDuck

14
มีตัวอย่างที่น่าสนใจของเครื่องมือ UNIX ที่ใช้กันทั่วไปซึ่งละเมิดข้อตกลงนี้โดยเจตนา: ddใช้key=valueไวยากรณ์ เหตุผลในการตัดสินใจออกแบบนี้คือเครื่องมือนี้ (ชื่อเล่น: d ata d estroyer) อาจทำให้เกิดความเสียหายจำนวนมากเมื่อใช้งานไม่ถูกต้อง โดยการบังคับให้ผู้ใช้ละทิ้งนิสัยปกติของพวกเขาพวกเขาบังคับให้ผู้ใช้คิดอย่างใกล้ชิดเกี่ยวกับสิ่งที่พวกเขากำลังทำ
Philipp

18
คุณแน่ใจหรือว่าเป็นเหตุผลที่dd? ฉันเชื่อว่ามันเป็นรหัสในเวลา (1970s?) เมื่อเคอร์เนลของ ARG_MAX มีขนาดเล็กเชลล์ไม่มีการเติมข้อมูลอัตโนมัติและ--long-argumentsไม่มีอยู่จริง ตั้งแต่นั้นมาก็ddยังดีกว่ากันได้ย้อนหลัง
Basile Starynkevitch

9
ddมีต้นกำเนิดมาจาก OS อื่น (นอกเหนือจาก UNIX) - scripting-language (JCL) บน IBM OS / 360 - ที่ซึ่งอนุสัญญาแตกต่างกันก่อนที่จะถูกย้ายไปยัง UNIX ไม่มากก็น้อย - ส่วนหนึ่งเป็นเพราะผู้ที่มีแนวโน้มที่จะใช้ ระบบก่อนหน้า
Baard Kopperud

29

ในแง่ของคนธรรมดา

เมื่ออยู่ในโรมทำตามที่ชาวโรมันทำ

  • หากแอป CLI ของคุณมีไว้สำหรับ Linux / Unix ให้ใช้-p valueหรือ--parameter valueตามระเบียบ Linux มีเครื่องมือสำหรับการวิเคราะห์พารามิเตอร์และแฟล็กดังกล่าวในวิธีที่ง่าย

ฉันมักจะทำสิ่งนี้:

while [[ $# > 0 ]]
do
key="$1"
case $key in
    --dummy)
    #this is a flag do something here
    ;;
    --audit_sessiones)
    #this is a flag do something here
    ;;
    --destination_path)
    # this is a key-value parameter
    # the value is always in $2 , 
    # you must shift to skip over for the next iteration
    path=$2
    shift
    ;;
    *)
    # unknown option
    ;;
esac
shift
done
  • หากแอป CLI ของคุณมีไว้สำหรับ Windows ให้ใช้/flagและ/flag:valueการประชุม

  • แอพบางตัวเช่น Oracle ไม่ได้ใช้ PARAMETER=VALUEสาธารณูปโภคของออราเคิลใช้

  • สิ่งหนึ่งที่ฉันต้องการทำคือนอกเหนือจากการยอมรับพารามิเตอร์ในบรรทัดคำสั่งให้ตัวเลือกในการใช้ parfileซึ่งเป็นไฟล์คู่ค่าคีย์เพื่อหลีกเลี่ยงการโยงพารามิเตอร์พารามิเตอร์ที่มีความยาว สำหรับสิ่งที่คุณควรระบุ--parfile mifile.parพารามิเตอร์เพิ่มเติม เห็นได้ชัดว่าหาก--parfileมีการใช้พารามิเตอร์อื่น ๆ ทั้งหมดจะถูกยกเลิกในความโปรดปรานของสิ่งที่อยู่ใน parfile

  • ข้อเสนอแนะเพิ่มเติมจะช่วยให้การใช้งานของบางตัวแปรสภาพแวดล้อมที่กำหนดเองตัวอย่างเช่นการตั้งค่าตัวแปรสภาพแวดล้อมจะทำให้มันไม่จำเป็นที่จะตั้งเสมอMYAPP_WRKSPACE=/tmp--wrkspace /tmp

  • ใน Linux อย่าลืมเพิ่มพารามิเตอร์การทำให้สมบูรณ์อัตโนมัติหมายถึงผู้ใช้สามารถพิมพ์สวิตช์ครึ่งหนึ่งแล้วกดTABและจากนั้นเชลล์จะทำให้เสร็จสมบูรณ์

1
มีเครื่องมือ GNU หลายอย่าง (เช่นgcc) จัดการตามที่@mifile.parคุณ--parfile mifile.parแนะนำ
Basile Starynkevitch

7
คุณแน่ใจหรือไม่ว่าสนใจตัวเลือกอื่น ๆ ทั้งหมดหากมีไฟล์พารามิเตอร์ มันฟังดูง่ายสำหรับฉันมากที่สุด
Jonathan Leffler

8
ฉันเห็นด้วยกับ Jonathan เกี่ยวกับไฟล์พารามิเตอร์ หากไฟล์พารามิเตอร์มีอยู่ฉันก็คาดหวังว่ามันจะถูกใช้สำหรับค่าเริ่มต้นโดยมีอาร์กิวเมนต์ที่กำหนดในบรรทัดคำสั่งที่นำมาใช้ทับส่วนบนใน parfile หากด้วยเหตุผลบางอย่างการใช้ parfile จะลดการใช้อาร์กิวเมนต์บรรทัดคำสั่งเพิ่มเติมดังนั้นการมีอาร์กิวเมนต์เพิ่มเติมควรเป็นข้อผิดพลาด
Eldritch Cheese

@EldritchCheese ในแอพพลิเคชั่น CLI ที่ฉันเขียนเมื่อกำหนดพาร์ไฟล์แล้วพารามิเตอร์ aditional จะสร้างข้อผิดพลาด
Tulains Córdova

1
หากใช้เชลล์ที่มีความสามารถตัวเลือก "config file พารามิเตอร์" นี้ไม่จำเป็น fooCmd -opt1 -opt2 $(cat more_options.opts)เช่นคุณเพียงแค่เขียน ดังนั้นฉันคาดว่าจะมีตัวเลือก "ไฟล์พารามิเตอร์การตั้งค่า" ถ้ามีให้โดยทั่วไปควรทำงานในลักษณะเดียวกัน
Brandin

19

สิ่งหนึ่งที่ยังไม่เกิดขึ้น:

ลองออกแบบซอฟต์แวร์ของคุณจากอาร์กิวเมนต์บรรทัดคำสั่งขึ้นไป ความหมาย:

ก่อนที่จะออกแบบฟังก์ชันการทำงานให้ออกแบบส่วนต่อประสานผู้ใช้

สิ่งนี้จะช่วยให้คุณสามารถเจาะลึกลงไปบนเคสแบบขอบและเคสทั่วไปในช่วงต้นได้ แน่นอนคุณจะยังคงนามธรรมทั้งภายนอกและภายใน แต่มันจะให้ผลลัพธ์ที่ดีกว่าการเขียนโค้ดทั้งหมดจากนั้นกระแทก CLI ลงไป

นอกจากนี้ให้ตรวจสอบ docopt ( http://docopt.org/ )

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


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

ฉันลอง docopt แล้ว แต่ฉันไม่ชอบ คลิกผลลัพธ์ในโค้ดที่สะอาดกว่ามากถึงแม้จะมีตัวเลือกที่ไม่เกะกะเมื่อคุณมีคำสั่งย่อย
jpmc26

2
มันเหมือนโฆษณามากเกินไป พูดถึงทรัพยากรเพียงครั้งเดียวถ้ามันมีความเกี่ยวข้อง .. แต่เมื่อถึงตอนนี้ 50% ของคำตอบของคุณดูเหมือนจะเป็นการส่งเสริมทรัพยากรภายนอก
Brandin

ฉันจะเรียกมันว่า 'ออกแบบแบบจำลองการใช้งานก่อน' การแยกประสบการณ์ผู้ใช้ออกจากฟังก์ชั่นการใช้งานอาจแตกต่างกันอย่างมากในหลาย ๆ กรณี (ข้อ จำกัด ของเครื่องมือมีผลต่อส่วนต่อประสาน)
ทองแดง

1
+1 สำหรับ Docopt มันแก้วิกฤติ CLI ทั้งหมดของฉันปราศจากความเจ็บปวดอย่างสมบูรณ์ บางครั้งมันเป็นเรื่องยากที่จะบอกได้โฆษณาจากความกระตือรือร้นของแท้ แต่ที่นี่มันเป็น - ฉันได้รับเป็นคนที่กระตือรือร้น Docopt สำหรับปีนี้ไม่มีส่วนเกี่ยวข้องในทางใด ๆ ;)
frnhr

3

มีความคิดเห็นที่มีค่าที่ให้ไว้แล้ว (@Florian, Basile) แต่ให้ฉันเพิ่ม ... OP บอกว่า

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

แต่ยังหมายเหตุ:

ฉันไม่ต้องการให้คำถามนี้เป็นแพลตฟอร์มหรือภาษาเฉพาะ

คุณต้องพิจารณากลุ่มเป้าหมายของคุณ - ผู้ดูแลระบบขั้นสูง แพลตฟอร์มใดที่พวกเขาทำงานตามปกติ - Win / Unix / Mac และแพลตฟอร์มใดที่แอพของคุณทำงานอยู่ ติดตามสิ่งที่อนุสัญญา CLI ได้รับการจัดตั้งขึ้นสำหรับแพลตฟอร์มนั้น ผู้ดูแลระบบ "ขั้นสูง" ของคุณต้องการ / ต้องการเครื่องมือที่ใช้ GUI หรือไม่

คุณต้องการให้อินเทอร์เฟซสอดคล้องภายในและมีเครื่องมือการดูแลอื่น ๆ ฉันไม่ต้องการที่จะหยุดและคิดว่าเป็นมันcmd -p <arg>หรือหรือcmd -p:<arg> cmd /p <arg>ฉันต้องการใบเสนอราคาเพราะมีช่องว่างหรือไม่ ฉันสามารถcmd -p <val1> <val2>หรือcmd -p <val1> -p <val2>หลายเป้าหมายได้หรือไม่ พวกเขาสั่งซื้อเฉพาะ? Overloadable? ไม่cmd -p2 <arg> -p1 <arg>ทำงานเกินไป? ไม่ls -l -r -t dir1 dir2== ls -trl dir1 dir2?

สำหรับเครื่องมือผู้ดูแลระบบ Unix ของฉันฉันเก็บคำแนะนำจากHeiner Shelldoradoไว้ในใจตลอดจนอ้างอิงอื่น ๆ ที่กล่าวถึง

สิ่งสำคัญเท่ากับการออกแบบ CLI คือเพื่อให้แน่ใจว่าแอปพลิเคชันของคุณได้รับการออกแบบให้ทำงานกับอาร์กิวเมนต์บรรทัดคำสั่งเหมือนกับจาก GUI - เช่น: ไม่มีตรรกะทางธุรกิจใน GUI หรือใช้คำสั่งทั่วไปที่เรียกว่าจาก GUI และ CLI

เครื่องมือการดูแลระบบที่ใช้ระบบปฏิบัติการ UNIX ส่วนใหญ่ได้รับการออกแบบมาก่อนเป็นเครื่องมือบรรทัดคำสั่งและ GUI ที่มีให้นั้นจะอำนวยความสะดวกในการ "สร้าง" ตัวเลือกสำหรับบรรทัดคำสั่ง วิธีการดังกล่าวทำให้ระบบอัตโนมัติใช้ไฟล์ตอบกลับ ฯลฯ และการจัดการแบบแฮนด์ออฟ (ใช้งานได้น้อยลงสำหรับฉัน!)

ในฐานะที่เป็นชุดเครื่องมือที่คลาสสิกใช้ w / วิธีนี้คือTcl / Tk ไม่แนะนำให้คุณสลับเครื่องมือ เพียงพิจารณาวิธีการออกแบบจากการเขียนแอปการจัดการบนพื้นฐานของ GUI ไปยังแอปเป็นเครื่องมือบรรทัดคำสั่งก่อน จากนั้นเลเยอร์ GUI ด้านบนเพื่อความสะดวก ในบางจุดคุณอาจค้นพบว่า GUI เป็นความเจ็บปวด (และเกิดข้อผิดพลาดได้ง่าย) หากคุณต้องทำการตั้งค่าหลาย ๆ ครั้งและป้อนตัวเลือกเดียวกันซ้ำไปซ้ำมาโดยทั่วไปแล้วคุณจะมองหาวิธีการอัตโนมัติ

โปรดจำไว้ว่าผู้ดูแลระบบของคุณอาจต้องพิมพ์ค่าที่ถูกต้องในช่องที่ถูกต้องอยู่แล้วดังนั้นคุณต้องใช้ความพยายามมากแค่ไหนด้วย w / GUI


เยี่ยมมากเลย! คำถามหนึ่งก็คือ: ฉันสามารถเรียกใช้. / this-script --hosts <hosts.txt
Florian Heigl
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.