Kapan dan bagaimana double-dash (-) diperkenalkan sebagai akhir dari pembatas pilihan di Unix / Linux?

49

Saya tidak berpikir shell / utilitas dalam Unix historis atau dalam sesuatu sebagai "baru" sebagai 4.4BSD didukung menggunakan tanda hubung ganda (atau dua tanda hubung berturut-turut) sebagai akhir dari pembatas pilihan . Dengan FreeBSD , Anda dapat melihat, misalnya, catatan yang diperkenalkan di rm manual dengan rilis 2.2.1 (1997). Tapi ini hanya dokumentasi untuk satu perintah.

Melihat changelog fileutils GNU tertua yang dapat saya temukan, saya melihat ini 1 (sedikit diubah):

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.

Ini mendahului Linux . Jelas untuk memperhitungkan fakta bahwa Anda mungkin ingin membuat file dengan nama yang mengandung jumlah digit yang sama dengan spesifikasi waktu (angka desimal delapan atau sepuluh digit) - daripada menentukan cap waktu untuk file yang ada ...


  • Jadi apakah itu posix.1 yang memperkenalkan dasbor ganda ( --) sebagai akhir dari pembatas pilihan di shell Unix?
  • Apakah ini semua dimulai karena beberapa orang ingin menggunakan angka dalam nama file touchpada awal 90-an dan kemudian ini berlanjut secara bertahap satu utilitas pada suatu waktu selama satu dekade ??
  • Apa komentar bersemangat di changelog tentang?
  • Kapan Pedoman 10 ( Argumen - harus diterima sebagai pembatas yang menunjukkan akhir opsi. [...] ) diperkenalkan ke Sintaks POSIX Utility ?

1. Berbeda dengan ini yaitu mendokumentasikan opsi panjang dalam semua penggunaan perintah secara global, yang tidak terkait. Di sisi lain, Anda dapat melihat referensi pembatas muncul di sesuatu seperti GNU rm.c pada tahun 2000 sebagai komentar, sebelum diekspos ke pengguna akhir pada tahun 2005 ( fungsi diagnose_leading_hyphen ). Tapi ini semua kemudian dan tentang kasus penggunaan yang sangat spesifik.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1
BSD4.3RENO setidaknya memiliki getoptyang didukung --.
Stéphane Chazelas
@ StéphaneChazelas Anda juga membuat komentar tentang getopt bukan satu-satunya api yang mampu menangani pembatas. Apakah itu berarti bahwa ini telah disediakan dan berfungsi sebelum benar-benar digunakan ?? Saya khawatir ini di luar jangkauan saya. Terima kasih!
2
Itu mungkin digunakan secara ad hoc oleh beberapa program acak tapi saya pikir itu pertama kali didokumentasikan ketika getoptditulis pada awal 1980-an. Jika seseorang bisa mendapatkan makalah getopt dari Uniforum '85, itu mungkin memberi sedikit sejarah.
Mark Plotnick
2
@ MarkPlotnick, sebenarnya getopt seperti yang ditemukan pada SysIII (1980) mendukung --.
Stéphane Chazelas

Jawaban:

38

Sejauh yang saya tahu, penggunaan --sebagai end-of-options-marker dimulai dengan shdan getoptdi System III Unix (1980).

Menurut sejarah keluarga Bourne Shell ini , Bourne Shell pertama kali muncul di Versi 7 Unix (1979). Tapi itu tidak memiliki cara untuk setuntuk memisahkan pilihan dari argumen . Jadi cangkang Bourne asli bisa lakukan:

  • set -e - aktifkan mode keluar-pada-kesalahan
  • set arg1 arg2 ...- menetapkan parameter posisi $1=arg1, $2=arg2dll

Tapi: set arg1 -e arg2akan memberikan $1=arg1, $2=arg2dan nyalakan keluar-on-error . Aduh.

System III Unix (1980) memperbaiki bug itu dan memperkenalkannya getopt. Menurut getopt's halaman manual :

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.

Sejauh yang saya tahu, itu adalah tempat pertama yang muncul.

Dari sana, tampaknya perintah lain mengadopsi --konvensi untuk menyelesaikan ambiguitas parsing argumen (seperti contoh dengan touchdan rmAnda kutip di atas) sepanjang hari-hari liar, standar tahun 1980-an.

Beberapa adopsi sedikit demi sedikit ini dikodifikasikan dalam POSIX.1 (1988), yang merupakan tempat komentar changelog tentang "Kludge yang diperlukan POSIX" berasal.

Tetapi tidak sampai POSIX.2 (1992) bahwa Pedoman Sintaks Utilitas diadopsi, yang berisi Pedoman 10 yang terkenal:

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.

Dan di situlah berubah dari menjadi "kludge" menjadi rekomendasi universal.

kayu
sumber
Terima kasih telah meluangkan waktu! Saya kebanyakan mengabaikan getopt dalam "riset" saya karena saya tidak mengerti mengapa utilitas / fungsi abstrak semacam itu diperlukan. Sekarang saya membaca ini diatur ulang (getopts) di beberapa titik untuk menangani kekosongan dll karena sysv getopttidak bisa. Saya akan membaca lebih lanjut tentang itu! Terima kasih lagi!
5
Jika Anda tidak memahami mengapa utilitas standar untuk parsing opsi baris perintah akan berguna, mungkin Anda belum mencoba menulis parser shell untuk opsi baris perintah? Agak menyebalkan! Tentu akan menyenangkan jika beberapa alat lain melakukan ini untuk saya ... Juga, perlu diingat: pada tahun 1980 tidak ada Python, tidak ada Ruby, tidak ada Jawa, tidak ada Perl, tidak ada PHP - bahkan C ++ belum ditemukan, dan seluruh gagasan "shell scripting" masih cukup baru. Jadi ide pengurai baris perintah standar masih cukup baru!
wwoods