Bạn đang bị ảo tưởng; sử dụng getopts
không yêu cầu đối số bắt buộc được bắt đầu bằng một lá cờ. Tôi đã cố gắng tìm một ví dụ phù hợp từ tập hợp các tập lệnh của tôi; đây là một xấp xỉ bán khá. Nó được gọi là rcsunco
và được sử dụng để hủy thanh toán từ RCS. Tôi đã không sửa đổi nó trong một thời gian, tôi thấy; Tôi sử dụng nó khá thường xuyên (vì tôi chưa di chuyển hoàn toàn từ RCS).
#!/bin/sh
#
# "@(#)$Id: rcsunco.sh,v 2.1 2002/08/03 07:41:00 jleffler Exp $"
#
# Cancel RCS checkout
# -V print version number
# -n do not remove or rename checked out file (like SCCS unget) (default)
# -r remove checked out file (default)
# -k keep checked out file as $file.keep
# -g checkout (unlocked) file after clean-up
# -q quiet checkout
: ${RCS:=rcs}
: ${CO:=co}
remove=yes
keep=no
get=no
quiet=
while getopts gknqrV opt
do
case $opt in
V) echo "`basename $0 .sh`: RCSUNCO Version $Revision: 2.1 $ ($Date: 2002/08/03 07:41:00 $)" |
rcsmunger
exit 0;;
g) get=yes;;
k) keep=yes;;
n) remove=no;;
q) quiet=-q;;
r) remove=yes;;
*) echo "Usage: `basename $0 .sh` [-{n|g}][-{r|k}] file [...]" 1>&2
exit 1;;
esac
done
shift $(($OPTIND-1))
for file in $*
do
rfile=$(rfile $file)
xfile=$(xfile $rfile)
if $RCS -u $rfile
then
if [ $keep = yes ]
then
if [ -f $xfile ]
then
mv $xfile $xfile.keep
echo "$xfile saved in $xfile.keep"
fi
elif [ $remove = yes ]
then rm -f $xfile
fi
if [ $get = yes ] && [ $remove = yes -o $keep = yes ]
then $CO $quiet $rfile
fi
fi
done
Nó chỉ là một xấp xỉ bán gần đúng; kịch bản lặng lẽ không làm gì nếu bạn không cung cấp bất kỳ tên tệp nào sau các đối số tùy chọn. Tuy nhiên, nếu bạn cần, bạn có thể kiểm tra xem các đối số bắt buộc có xuất hiện sau 'thay đổi' hay không. Một kịch bản khác của tôi không có đối số bắt buộc. Nó chứa:
...
shift $(($OPTIND - 1))
case $# in
2) case $1 in
install) MODE=Installation;;
uninstall) MODE=Uninstallation;;
*) usage;;
esac;;
*) usage;;
esac
Vì vậy, rằng lệnh (jlss
) có thể mất đối số tùy chọn như -d $HOME
, nhưng đòi hỏi một trong hai install
hoặc uninstall
theo sau là tên của một cái gì đó để cài đặt. Phương thức cơ bản về sử dụng là:
jlss install program
Nhưng chế độ tùy chọn là:
jlss -d $HOME -u me -g mine -x -p install program
Tôi không hiển thị tất cả jlss
bởi vì nó có khoảng 12 tùy chọn - nó không phải là nhỏ gọn như rcsunco
.
Nếu bạn đang đối phó với đối số bắt buộc trước khi đối số tùy chọn, sau đó bạn sẽ phải làm một chút công việc:
- Bạn muốn nhận các đối số bắt buộc, chuyển chúng ra khỏi đường.
- Sau đó, bạn xử lý các đối số tùy chọn bằng cờ.
- Cuối cùng, nếu thích hợp, bạn xử lý thêm đối số 'tên tệp'.
Nếu bạn đang đối phó với các đối số bắt buộc xen kẽ với các đối số tùy chọn (cả trước và sau các đối số bắt buộc), thì bạn vẫn còn nhiều việc phải làm. Điều này được sử dụng bởi nhiều hệ thống VCS; CVS và GIT đều có cơ sở:
git -global option command [-sub option] [...]
Ở đây, bạn chạy một vòng getopts
để nhận các tùy chọn toàn cầu; lấy các đối số bắt buộc; và chạy vòng lặp getopts
thứ hai để nhận các tùy chọn phụ (và có thể chạy vòng lặp cuối cùng qua đối số 'tên tệp').
Không phải cuộc sống vui vẻ phải không?
Điều này có vẻ như nó thực hiện chính xác những gì tôi muốn. Một câu hỏi với điều này, tuy nhiên: nếu tôi muốn cho phép một lá cờ mà có một đối số (ví dụ, -l file.txt), những gì sẽ là cú pháp? Cảm ơn một lần nữa. –
Tham khảo trang người dùng getopt để biết điều đó. Tóm lại: nối thêm dấu hai chấm vào tùy chọn (ví dụ: '" -rv: x "', yêu cầu v để nhận một đối số). Các tùy chọn dài cũng được hỗ trợ, đó là một cách nó vượt trội hơn các getopts được xây dựng. Lưu ý rằng bạn sẽ phải tự mình xử lý đối số phi tùy chọn bổ sung. – Sorpigal
Cảm ơn bạn rất nhiều. Một phản ứng tuyệt vời. –