Khi bạn viết bit phân tích dòng lệnh của mã, bạn chỉ định tùy chọn nào lấy đối số và tùy chọn nào không. Ví dụ: trong tập lệnh shell chấp nhận một -h
tùy chọn (ví dụ như trợ giúp) và một -a
tùy chọn cần lấy một đối số, bạn làm
opt_h=0 # default value
opt_a=""
while getopts 'a:h' opt; do
case $opt in
h) opt_h=1 ;;
a) opt_a="$OPTARG" ;;
esac
done
echo "h: $opt_h"
echo "a: $opt_a"
Các a:h
chút nói: "Tôi đang mong đợi để phân tích hai lựa chọn, -a
và -h
, và -a
nên một cuộc tranh cãi" (đó là :
sau a
đó nói với các phân tích cú pháp mà -a
phải mất một đối số).
Do đó, không bao giờ có bất kỳ sự mơ hồ nào trong đó một tùy chọn kết thúc, nơi giá trị của nó bắt đầu và nơi một tùy chọn khác bắt đầu sau đó.
Chạy nó:
$ bash test.sh -h -a hello
h: 1
a: hello
$ bash test.sh -h -ahello
h: 1
a: hello
$ bash test.sh -hahello
h: 1
a: hello
Đây là lý do tại sao bạn hầu như không nên viết trình phân tích cú pháp dòng lệnh của riêng bạn để phân tích các tùy chọn.
Chỉ có một trường hợp trong ví dụ này là khó khăn. Việc phân tích cú pháp thường dừng ở tùy chọn không phải tùy chọn đầu tiên, vì vậy khi bạn có nội dung trên dòng lệnh trông giống như tùy chọn:
$ bash test.sh -a hello -world
test.sh: illegal option -- w
test.sh: illegal option -- o
test.sh: illegal option -- r
test.sh: illegal option -- l
test.sh: illegal option -- d
h: 0
a: hello
Sau đây giải quyết rằng:
$ bash test.sh -a hello -- -world
h: 0
a: hello
Các --
tín hiệu kết thúc các tùy chọn dòng lệnh và -world
bit còn lại để chương trình thực hiện bất cứ điều gì nó muốn (nó nằm trong một trong các biến vị trí).
Nhân tiện, đó là cách bạn loại bỏ một tệp có dấu gạch ngang khi bắt đầu tên tệp của nó rm
.
CHỈNH SỬA :
Các tiện ích được viết bằng C gọi getopt()
(khai báo unistd.h
) hoạt động khá giống nhau. Trong thực tế, đối với tất cả chúng ta đều biết, các bash
chức năng getopts
có thể được thực hiện bằng một cuộc gọi đến các chức năng thư viện C getopt()
. Perl, Python và các ngôn ngữ khác có thư viện phân tích cú pháp dòng lệnh tương tự và rất có thể chúng thực hiện phân tích cú pháp theo cách tương tự.
Một số trong những thói quen thư viện getopt
và getopt
giống như này cũng xử lý các tùy chọn "dài". Chúng thường được bắt đầu bằng dấu gạch ngang kép ( --
) và các tùy chọn dài có các đối số thường làm như vậy sau một dấu bằng, ví dụ --block-size=SIZE
tùy chọn [một số triển khai] du
tiện ích (cũng cho phép -B SIZE
chỉ định điều tương tự).
Các hướng dẫn lý do thường được viết để hiển thị một khoảng trống ở giữa các tùy chọn ngắn và các đối số của chúng có lẽ là để dễ đọc.
EDIT : Các công cụ thực sự cũ, chẳng hạn như dd
và tar
các tiện ích, có các tùy chọn mà không có dấu gạch ngang trước mặt chúng. Điều này hoàn toàn là vì lý do lịch sử và để duy trì khả năng tương thích với phần mềm dựa vào chúng để hoạt động chính xác theo cách đó. Các tar
tiện ích đã đạt được khả năng chụp tùy chọn với dấu gạch ngang trong thời gian gần đây hơn. Hướng dẫn sử dụng BSD để tar
gọi các tùy chọn kiểu cũ cho "cờ được gói".