เมื่อใดและอย่างไร double-dash (-) ถูกนำมาใช้เป็นจุดสิ้นสุดของตัวเลือกตัวคั่นใน Unix / Linux


49

ฉันไม่คิดว่าเปลือก / สาธารณูปโภคในประวัติศาสตร์ Unix หรือในสิ่งที่เป็น "ล่าสุด" เป็น4.4BSDสนับสนุนการใช้สองเส้นประ (หรือสองยัติภังค์ติดต่อกัน) ในฐานะที่เป็นส่วนท้ายของตัวเลือกตัวคั่น ด้วยFreeBSDคุณสามารถดูตัวอย่างข้อความที่แนะนำในrm manpagesด้วย2.2.1 รีลีส (1997) แต่นี่เป็นเพียงเอกสารประกอบสำหรับคำสั่งเดียว

ดูGNU fileutils changelog ที่เก่าแก่ที่สุดที่ฉันสามารถหาได้ฉันเห็นสิ่งนี้1 (เปลี่ยนแปลงเล็กน้อย):

Tue Aug 28 18:05:24 1990  David J. MacKenzie  (djm at albert.ai.mit.edu)

* touch.c (main): Don't interpret first non-option arg as a   <---
  time if `--' is given (POSIX-required kludge).  
* touch.c: Add long-named options.
* Many files: Include <getopt.h> instead of "getopt.h" since
  getopt.h will be in the GNU /usr/include.
* install.c: Declare some functions.
* touch.c, getdate.y, posixtime.y, mktime.c: New files, from bin-src.
* posixtime.y: Move year from before time to after it (but
  before the seconds), for 1003.2 draft 10.

นี้ถือกำเนิดลินุกซ์ เป็นที่ชัดเจนว่าบัญชีของคุณอาจต้องการสร้างไฟล์ที่มีชื่อที่มีตัวเลขหลักเดียวกับการระบุเวลา(หมายเลขทศนิยมแปดหรือสิบหลัก) - แทนที่จะระบุเวลาสำหรับไฟล์ที่มีอยู่ ...


  • ดังนั้นมันคือposix.1ที่แนะนำ double-dash ( --) เป็นจุดสิ้นสุดของตัวเลือกคั่นใน Unix shells หรือไม่?
  • ทั้งหมดนี้เริ่มต้นขึ้นหรือไม่เพราะบางคนต้องการใช้ตัวเลขในชื่อไฟล์ด้วยtouchในช่วงต้นยุค 90 และจากนั้นสิ่งนี้ก็เกิดขึ้นในยูทิลิตี้ทีละน้อยทีละหนึ่งทศวรรษ?
  • ความคิดเห็นที่มีชีวิตชีวาในการเปลี่ยนแปลงคืออะไรเกี่ยวกับ?
  • เมื่อใดที่Guideline 10 ( อาร์กิวเมนต์ - ควรได้รับการยอมรับเป็นตัวคั่นเพื่อระบุจุดสิ้นสุดของตัวเลือก [... ] ) แนะนำให้รู้จักกับ POSIX Utility Syntax ?

1. ตรงข้ามกับสิ่งนี้คือการบันทึกตัวเลือกแบบยาวในการใช้คำสั่งทั้งหมดทั่วโลกซึ่งไม่เกี่ยวข้อง ในทางกลับกันคุณสามารถดูการอ้างอิงถึงตัวคั่นปรากฏในสิ่งที่ต้องการGNU rm.cในปี 2000 เป็นความคิดเห็นก่อนที่จะเปิดเผยต่อผู้ใช้ปลายทางในปี 2005 ( ฟังก์ชั่นdiagnose_leading_hyphen ) แต่นี่เป็นสิ่งที่เกิดขึ้นในภายหลังและเป็นกรณีการใช้งานที่เฉพาะเจาะจง


1
BSD4.3RENO อย่างน้อยมีที่รองรับgetopt --
Stéphane Chazelas

@ StéphaneChazelasคุณยังได้แสดงความคิดเห็นเกี่ยวกับgetopt ที่ไม่ได้เป็นเพียง api คนเดียวที่สามารถจัดการกับตัวคั่นได้ นั่นหมายความว่าสิ่งนี้ได้รับการจัดหาให้และทำงานก่อนที่มันจะถูกใช้จริง ๆ หรือไม่? ฉันกลัวว่านี่จะเกินฉัน ขอขอบคุณ!

2
มันอาจใช้เป็นประจำโดยโปรแกรมสุ่มหลาย ๆ อัน แต่ฉันคิดว่ามันกลายเป็นเอกสารครั้งแรกเมื่อgetoptถูกเขียนขึ้นในต้นปี 1980 หากใครบางคนสามารถรับกระดาษ getopt จาก Uniforum '85 นั่นอาจทำให้ประวัติศาสตร์
Mark Plotnick

2
@MarkPlotnick จริง getopt เป็นที่พบใน SysIII (1980) --การสนับสนุน
Stéphane Chazelas

คำตอบ:


38

เท่าที่ฉันสามารถบอกได้การใช้--as-end-of-options-marker เริ่มต้นด้วยshและgetoptใน System III Unix (1980)

จากประวัติของตระกูล Bourne Shellนี้บอร์นเชลล์ได้ปรากฏตัวครั้งแรกในเวอร์ชั่น 7 Unix (1979) แต่มันไม่ได้มีวิธีการsetที่จะแยกตัวเลือกจากการขัดแย้ง ดังนั้นเชลล์เป้าหมายเดิมสามารถทำได้:

  • set -e - เปิดโหมดทางออกข้อผิดพลาด
  • set arg1 arg2 ...- ชุดพารามิเตอร์ตำแหน่ง$1=arg1, $2=arg2ฯลฯ

แต่: set arg1 -e arg2จะให้คุณ$1=arg1, $2=arg2และเปิดทางออกต่อข้อผิดพลาด อ๊ะ

ระบบยูนิกซ์ III (1980) getoptการแก้ไขข้อผิดพลาดที่และแนะนำ ตามที่getopt's หน้าคน :

NAME
   getopt - parse command options

SYNOPSIS
   set -- `getopt optstring $∗`

DESCRIPTION
   Getopt is used to break up options in command lines for easy parsing by
   shell procedures, and to check  for  legal  options.   Optstring  is  a
   string  of  recognized  option letters (see getopt(3C)); if a letter is
   followed by a colon, the option is expected to have an  argument  which
   may or may not be separated from it by white space.  The special option
   -- is used to delimit the end of the options.  Getopt will place --  in
   the  arguments  at  the  end  of  the  options, or recognize it if used
   explicitly.  The shell arguments ($1 $2 . . .) are reset so  that  each
   option  is  preceded  by a - and in its own shell argument; each option
   argument is also in its own shell argument.

เท่าที่ฉันสามารถบอกได้นั่นคือที่แรกที่มันปรากฏ

จากที่นั่นดูเหมือนว่าคำสั่งอื่น ๆ ใช้การ--ประชุมเพื่อแก้ปัญหาการแยกวิเคราะห์ความกำกวม (เช่นตัวอย่างที่มีtouchและrmคุณอ้างถึงข้างต้น) ตลอดทั้งวันที่ป่าเถื่อนและไร้มาตรฐานในยุค 80

บางส่วนของการรับเลี้ยงบุตรบุญธรรมทีละน้อยเหล่านี้ได้รับการประมวลในPOSIX.1 (1988) ซึ่งเป็นที่ที่ความคิดเห็นเกี่ยวกับการเปลี่ยนแปลงเกี่ยวกับ "kludge ที่ต้องใช้ POSIX" มาจาก

แต่มันไม่เป็นเช่นนั้นจนกระทั่งPOSIX.2 (1992) ที่ใช้แนวทางไวยากรณ์ของยูทิลิตี้ซึ่งมีแนวทางที่มีชื่อเสียง 10:

Guideline 10:    The argument "--" should be accepted as a delimiter
                 indicating the end of options.  Any following
                 arguments should be treated as operands, even if they
                 begin with the '-' character.  The "--" argument
                 should not be used as an option or as an operand.

และนั่นคือสิ่งที่มันเปลี่ยนจากการเป็น "kludge" ไปสู่ข้อเสนอแนะที่เป็นสากล


ขอบคุณที่สละเวลา! ฉันมักจะมองข้าม getopt ใน "การวิจัย" ของฉันเพราะฉันไม่เข้าใจว่าทำไมต้องมีอรรถประโยชน์ / ฟังก์ชั่นที่เป็นนามธรรม ตอนนี้ฉันอ่านสิ่งนี้ถูก reegineered (getopts)ในบางจุดเพื่อจัดการกับช่องว่าง ฯลฯ เนื่องจาก sysv getoptไม่สามารถทำได้ ฉันจะอ่านเพิ่มเติมเกี่ยวกับมัน! ขอบคุณอีกครั้ง!

5
หากคุณไม่เข้าใจว่าทำไมยูทิลิตี้มาตรฐานสำหรับการแยกวิเคราะห์ตัวเลือกบรรทัดคำสั่งจะมีประโยชน์บางทีคุณยังไม่ได้ลองเขียน shell parser สำหรับตัวเลือกบรรทัดคำสั่ง? มันช่างเป็นความเจ็บปวด! แน่นอนว่าจะดีถ้าเครื่องมืออื่น ๆ ทำสิ่งนี้ให้ฉัน ... นอกจากนี้โปรดจำไว้ว่า: ในปี 1980 ไม่มี Python ไม่มี Ruby ไม่มี Java ไม่มี Perl ไม่ PHP - แม้แต่ C ++ ก็ยังไม่ได้ถูกคิดค้นและ แนวคิดทั้งหมดของ "การเขียนสคริปต์เปลือกหอย" ยังคงใหม่อยู่ ดังนั้นความคิดของตัวแยกวิเคราะห์บรรทัดคำสั่งมาตรฐานจึงยังแปลกใหม่อยู่!
วูดส์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.