2014-10-17 15 views
6

Khi sử dụng getopt để phân tích cú pháp tham số dòng lệnh, bạn có thể đặt dấu cách giữa cờ tùy chọn và đối số cho đối số bắt buộc nhưng không đặt cho đối số tùy chọn. Các đối số tùy chọn sẽ chỉ được phân tích cú pháp nếu chúng nằm ngay sau tùy chọn.Tại sao tôi không thể có khoảng cách giữa tùy chọn và đối số tùy chọn bằng cách sử dụng getopt?

TEMP=`getopt -o p:q:: -n 'mkqueue.sh' -- "[email protected]"` 

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi 

# Note the quotes around `$TEMP': they are essential! 
eval set -- "$TEMP" 

# Now go through all the options 
while true ; do 
    case "$1" in 
     -p) echo "Option p, argument \`$2'" ; shift 2 ;; 
     -q) 
      case "$2" in 
       "") echo "Option q, no argument"; shift 2 ;; 
       *) echo "Option q, argument \`$2'" ; shift 2 ;; 
      esac ;; 
     --) shift ; break ;; 
     *) echo "Internal error!" ; exit 1 ;; 
    esac 
done 

(Dựa trên điều này: http://software.frodo.looijaard.name/getopt/docs/getopt-parse.bash)

Khi tôi chạy kịch bản mà không có đối số tùy chọn hoạt động:

./mkqueue.sh -p adfsa -q 
Option p, argument `adfsa' 
Option q, no argument 

Nếu tôi cố gắng thêm đối số tùy chọn để -q với một không gian ở giữa nó không hoạt động:

./mkqueue.sh -p adfsa -q sdfasdfa 
Option p, argument `adfsa' 
Option q, no argument 

Nó hoạt động nếu bạn không có tốc độ ở giữa tùy chọn và đối số, mặc dù đối số bắt buộc hoạt động với không gian:

./mkqueue.sh -p adfsa -qsdfasdfa 
Option p, argument `adfsa' 
Option q, argument `sdfasdfa' 

Có khắc phục sự cố này không?

+2

Nếu được phép, bạn sẽ gặp phải sự cố khác. Giả sử chương trình của bạn cũng chấp nhận một đối số vị trí. Nên './a.out -q foo bar' được phân tách thành' ./a.out -qfoo bar' hoặc là './a.out -q - foo bar'? – 5gon12eder

+1

@ 5gon12eder, nếu bạn có câu trả lời như vậy, bạn ít nhất cũng có ý kiến ​​của tôi. Nó giải thích "tại sao", đó là tiêu đề của câu hỏi này yêu cầu. :) –

Trả lời

8

Đó giới hạn được ghi chép lại trong manpage cho getopt:

Một lựa chọn ngắn đơn giản là một `-' theo sau là một nhân vật tùy chọn ngắn. Nếu tùy chọn có một đối số bắt buộc, nó có thể được viết trực tiếp sau ký tự tùy chọn hoặc là tham số tiếp theo (ví dụ: được phân tách bằng khoảng trống trên dòng lệnh). Nếu tùy chọn có đối số tùy chọn, nó phải được ghi trực tiếp sau ký tự tùy chọn nếu có.

Cho phép "đối số tùy chọn tùy chọn", chúng thường được coi là ý tưởng tồi. Các Posix Utility Syntax Guidelines, ví dụ, bao gồm:

Hướng dẫn 7: Option-luận không nên bắt buộc.

Lý do cơ bản cho hướng dẫn này là do quy ước đối số cho tùy chọn dòng lệnh có thể là bất kỳ chuỗi nào. Nó có thể trông giống như một lựa chọn khác, ví dụ. Nó có thể là chuỗi chữ số --, thường chỉ ra phần cuối của danh sách tùy chọn. Nó có thể là một chuỗi rỗng. Bất cứ điều gì.

Vấn đề với "đối số tùy chọn tùy chọn" là cách duy nhất để biết rằng đối số tùy chọn tùy chọn không được cung cấp là nhận ra đối số sau dưới dạng tùy chọn hoặc --. Nhưng điều đó có nghĩa là giá trị của đối số tùy chọn không thể bắt đầu bằng -. Ngoài ra, bạn có thể chọn giải pháp được thực hiện bởi tiện ích dòng lệnh getopt, đó là yêu cầu đối số tùy chọn ngay lập tức tuân theo tùy chọn, không có khoảng trống xen kẽ (nghĩa là, đang ở cùng một từ). Nhưng trong trường hợp đó, đối số tùy chọn không thể là một chuỗi rỗng. Thay vì tạo ra các quy tắc phức tạp để giải quyết những sự mơ hồ này, giải pháp đơn giản - được đề xuất bởi Posix (và, với rất ít quyền hạn hơn), là không cho phép các đối số tùy chọn là tùy chọn.Nếu có một giá trị chung cho một tùy chọn dòng lệnh và bạn muốn đơn giản hóa cuộc sống của người dùng bằng cách không yêu cầu nó được gõ, sau đó thực hiện hai tùy chọn dòng lệnh khác nhau, một trong số đó có một đối số và không. Các kỹ thuật phổ biến bao gồm sử dụng ký tự chữ thường cho phiên bản không có đối số và ký tự chữ hoa tương ứng cho phiên bản có đối số hoặc sử dụng tùy chọn dài (--option) cho phiên bản đó.

Đối với những người thích rậm rạp và đóng gói giải thích, các Posix rationale giải thích rằng:

Hướng dẫn 7 cho phép bất kỳ chuỗi là một lựa chọn đối số; một đối số tùy chọn có thể bắt đầu bằng bất kỳ ký tự nào, có thể là - hoặc -- và có thể là một chuỗi rỗng. Ví dụ, các lệnh pr -h -, pr -h --, pr -h -d, pr -h +2pr -h '' chứa các tùy chọn-luận -, --, -d, +2, và một chuỗi rỗng, tương ứng. Ngược lại, lệnh pr -h -- -d xử lý -d dưới dạng một tùy chọn, không phải là một đối số, bởi vì -- là một đối số tùy chọn ở đây, không phải là dấu phân cách.

+0

Đó là một lời giải thích tốt, và hoàn thành, nhưng tôi nghĩ rằng một chút dày đặc. Việc giải nén các ví dụ lý do một chút có thể hữu ích (không phải ai cũng biết '--' nghĩa là gì, f'rinstance). –

Các vấn đề liên quan