Khi nào và làm thế nào dấu gạch ngang kép (-) được giới thiệu như là sự kết thúc của dấu phân cách tùy chọn trong Unix / Linux?


49

Tôi không nghĩ hệ vỏ / tiện ích trong Unix lịch sử cũng như trong "gần đây" như 4.4BSD được hỗ trợ bằng cách sử dụng dấu gạch ngang kép (hoặc hai dấu gạch nối liên tiếp) làm dấu chấm hết cho dấu phân cách tùy chọn . Ví dụ, với FreeBSD , bạn có thể thấy một ghi chú được giới thiệu trong các rm trangbản phát hành 2.2.1 (1997). Nhưng đây chỉ là tài liệu cho một lệnh.

Nhìn vào tập tin thay đổi tập tin GNU cũ nhất mà tôi có thể tìm thấy, tôi thấy cái này 1 (thay đổi một chút):

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.

Điều này có trước Linux . Đó là rõ ràng vào tài khoản cho thực tế là bạn có thể muốn tạo một tập tin với một tên có chứa cùng số chữ số là một thời gian đặc điểm kỹ thuật (số thập phân tám hoặc mười chữ số) - chứ không phải là chỉ định một dấu thời gian cho một tập tin hiện có ...


  • Vì vậy, nó là posix.1 đã giới thiệu dấu gạch ngang kép ( --) như là một kết thúc của dấu phân cách tùy chọn trong shell Unix không?
  • Tất cả đã bắt đầu bởi vì một số người muốn sử dụng chữ số trong tên tệp với touch vào đầu những năm 90 và sau đó điều này đã diễn ra trong một tiện ích thời trang từng phần trong một thập kỷ ??
  • Nhận xét tinh thần trong các thay đổi về là gì?
  • Khi nào Hướng dẫn 10 ( Đối số - nên được chấp nhận làm dấu phân cách chỉ ra kết thúc của các tùy chọn. [...] ) được giới thiệu cho Cú pháp tiện ích POSIX ?

1. Trái ngược với điều này tức là ghi lại các tùy chọn dài trong tất cả các lệnh sử dụng trên toàn cầu, không liên quan. Mặt khác, bạn có thể thấy tham chiếu đến dấu phân cách xuất hiện trong một cái gì đó như GNU rm.c vào năm 2000 dưới dạng nhận xét, trước khi được tiếp xúc với người dùng cuối vào năm 2005 ( hàm chẩn đoán_lead_hyphen ). Nhưng đây là tất cả muộn hơn và là về một trường hợp sử dụng rất cụ thể.


1
BSD4.3RENO ít nhất đã có một getopthỗ trợ --.
Stéphane Chazelas

@ StéphaneChazelas Bạn cũng đã nhận xét về getopt không phải là api duy nhất có thể đối phó với dấu phân cách. Điều đó có nghĩa là cái này đã được cung cấp và hoạt động trước khi nó thực sự được sử dụng ?? Tôi sợ điều này vượt quá tôi. Cảm ơn bạn!

2
Nó có thể được sử dụng trên cơ sở đặc biệt bởi một số chương trình ngẫu nhiên nhưng tôi nghĩ nó lần đầu tiên được ghi nhận khi getoptđược viết vào đầu những năm 1980. Nếu ai đó có thể lấy giấy getopt từ Uniforum '85, điều đó có thể mang lại một số lịch sử.
Đánh dấu Plotnick

2
@MarkPlotnick, thực sự là getopt như được tìm thấy trên SysIII (1980) hỗ trợ --.
Stéphane Chazelas

Câu trả lời:


38

Theo như tôi có thể nói, việc sử dụng --làm dấu hiệu tùy chọn kết thúc bắt đầu bằng shgetopttrong System III Unix (1980).

Theo lịch sử của gia đình Bourne Shell , Bourne Shell lần đầu tiên xuất hiện trong Phiên bản 7 Unix (1979). Nhưng nó không có cách nào setđể tách các tùy chọn khỏi các đối số . Vì vậy, vỏ Bourne ban đầu có thể làm:

  • set -e - bật chế độ thoát lỗi
  • set arg1 arg2 ...- thiết lập các thông số vị trí $1=arg1, $2=arg2vv

Nhưng: set arg1 -e arg2sẽ cung cấp cho bạn $1=arg1, $2=arg2bật exit-on-lỗi . Rất tiếc.

Hệ thống III Unix (1980) đã sửa lỗi đó và giới thiệu getopt. Theo tranggetopt của người đàn ông :

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.

Theo như tôi có thể nói, đó là nơi đầu tiên nó xuất hiện.

Từ đó, dường như các lệnh khác đã thông qua --quy ước để giải quyết sự mơ hồ phân tích đối số (chẳng hạn như các ví dụ với touchrmbạn trích dẫn ở trên) trong suốt những ngày hoang dã, không chuẩn của những năm 1980.

Một số trong những việc áp dụng từng phần này đã được mã hóa trong POSIX.1 (1988), đó là nơi nhận xét thay đổi về "loại bùn yêu cầu POSIX" xuất phát.

Nhưng mãi đến POSIX.2 (1992), Nguyên tắc Cú pháp Tiện ích mới được thông qua, trong đó có Hướng dẫn 10 nổi tiếng:

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.

Và đó là nơi nó đi từ một "bùn" đến một khuyến nghị phổ quát.


Cảm ơn bạn đã dành thời gian! Tôi hầu như đã bỏ qua getopt trong "nghiên cứu" của mình vì tôi không hiểu tại sao loại tiện ích / chức năng trừu tượng hóa lại được yêu cầu. Bây giờ tôi đọc điều này đã được xem xét lại (getopts) tại một số điểm để đối phó với khoảng trống, vv như sysv là getoptkhông thể. Tôi sẽ đọc thêm về nó! Cảm ơn một lần nữa!

5
Nếu bạn không hiểu tại sao một tiện ích tiêu chuẩn để phân tích các tùy chọn dòng lệnh sẽ hữu ích, có lẽ bạn đã không thử viết trình phân tích cú pháp shell cho các tùy chọn dòng lệnh? Đó là một nỗi đau! Chắc chắn sẽ rất tuyệt nếu một số công cụ khác đã làm điều này cho tôi ... Ngoài ra, hãy nhớ rằng: năm 1980 không có Python, không có Ruby, không có Java, không có Perl, không có PHP - thậm chí C ++ chưa được phát minh và toàn bộ ý tưởng "shell scripting" vẫn còn khá mới. Vì vậy, ý tưởng về trình phân tích cú pháp dòng lệnh tiêu chuẩn vẫn còn khá mới lạ!
wwoods
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.