getopt
ve getopts
farklı yaratıklardır ve insanların yaptıklarıyla ilgili yanlış anlaşılmaları var gibi görünüyor. getopts
Bir komuta dahili olan bash
bir döngüde işlem komut satırı seçeneklerine ve daha fazla onları işleyebilir Yerleşik değişkenler, böylece için sırayla her bulunan seçenek ve değer atama. getopt
Bununla birlikte, harici bir yardımcı programdır ve seçeneklerinizi sizin için bash getopts
, Perl Getopt
modülü veya Python optparse
/ argparse
modülleri gibi işlemez . Tek getopt
yapmanız gereken, geçirilen seçenekleri kanonik hale getirmek - yani daha standart bir forma dönüştürmek, böylece bir kabuk betiğinin bunları işlemesini kolaylaştırmaktır. Örneğin, bir uygulaması getopt
aşağıdakileri dönüştürebilir:
myscript -ab infile.txt -ooutfile.txt
bunun içine:
myscript -a -b -o outfile.txt infile.txt
Gerçek işlemi kendiniz yapmanız gerekir. getopt
Seçenekleri belirleme yolunda çeşitli kısıtlamalar yaparsanız hiç kullanmanız gerekmez :
- argüman başına yalnızca bir seçenek koyun;
- tüm seçenekler herhangi bir konum parametresinden önce gelir (örn. seçenek olmayan argümanlar);
- değer içeren seçenekler için (örn.
-o
yukarıda), değerin ayrı bir bağımsız değişken olarak (boşluktan sonra) gitmesi gerekir.
Neden kullanmak getopt
yerine getopts
? Bunun temel nedeni, yalnızca GNU'nun getopt
uzun adlı komut satırı seçenekleri için destek vermesidir. 1 (Linux'ta GNU getopt
varsayılan değerdir. Mac OS X ve FreeBSD temel ve çok kullanışlı değildir getopt
, ancak GNU sürümü yüklenebilir; aşağıya bakın.)
Örneğin, işte şöyle getopt
bir senaryomdan GNU kullanımına bir örnek javawrap
:
# NOTE: This requires GNU getopt. On Mac OS X and FreeBSD, you have to install this
# separately; see below.
TEMP=`getopt -o vdm: --long verbose,debug,memory:,debugfile:,minheap:,maxheap: \
-n 'javawrap' -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
VERBOSE=false
DEBUG=false
MEMORY=
DEBUGFILE=
JAVA_MISC_OPT=
while true; do
case "$1" in
-v | --verbose ) VERBOSE=true; shift ;;
-d | --debug ) DEBUG=true; shift ;;
-m | --memory ) MEMORY="$2"; shift 2 ;;
--debugfile ) DEBUGFILE="$2"; shift 2 ;;
--minheap )
JAVA_MISC_OPT="$JAVA_MISC_OPT -XX:MinHeapFreeRatio=$2"; shift 2 ;;
--maxheap )
JAVA_MISC_OPT="$JAVA_MISC_OPT -XX:MaxHeapFreeRatio=$2"; shift 2 ;;
-- ) shift; break ;;
* ) break ;;
esac
done
Bu, --verbose -dm4096 --minh=20 --maxhe 40 --debugfi="/Users/John Johnson/debug.txt"
benzer veya benzer seçenekleri belirlemenizi sağlar . Çağrının etkisi getopt
, seçenekleri --verbose -d -m 4096 --minheap 20 --maxheap 40 --debugfile "/Users/John Johnson/debug.txt"
daha kolay işleyebilmeniz için seçenekleri standartlaştırmaktır . Etrafta alıntılar yapmak "$1"
ve "$2"
içinde boşluk olan argümanların düzgün bir şekilde ele alınmasını sağlamak önemlidir.
İlk 9 satırı silerseniz ( eval set
satır boyunca her şey ), kod yine de çalışır ! Ancak, kodunuz ne tür seçenekleri kabul ettiğine göre çok daha pickier olacaktır: Özellikle, yukarıda açıklanan "standart" formdaki tüm seçenekleri belirtmeniz gerekir. Kullanımı ile getopt
, ancak, grup tek harfli seçenekleri, uzun seçenekler, kullanım ya kısa olmayan belirsiz formlarını kullanabilirsiniz --file foo.txt
veya --file=foo.txt
iki stil, kullanımı -m 4096
veya -m4096
stil, herhangi bir sırada seçeneklerini ve olmayan seçenekleri mix vb getopt
ayrıca tanınmayan veya belirsiz seçenekler bulunursa bir hata mesajı verir.
NOT : Aslında temel ve GNU olmak üzere tamamen farklı iki sürümü vardır . 2 Temel oldukça bozuk: Sadece uzun seçenekleri işlemekle kalmaz, aynı zamanda argümanların veya boş argümanların içindeki gömülü boşlukları bile işleyemez, oysa bunu doğru yapar. Yukarıdaki kod temel olarak çalışmaz . GNU Linux'a varsayılan olarak yüklenir, ancak Mac OS X ve FreeBSD'de ayrı olarak yüklenmesi gerekir. Mac OS X'te MacPorts'u ( http://www.macports.org ) yükleyin ve GNU'yu (genellikle içine ) yüklemek için yapın ve bunun önündeki kabuk yolunuzda olduğundan emin olungetopt
getopt
getopt
getopt
getopts
getopt
getopt
sudo port install getopt
getopt
/opt/local/bin
/opt/local/bin
/usr/bin
. FreeBSD'de yükleyinmisc/getopt
.
Kendi programınız için örnek kodu değiştirmek için hızlı bir kılavuz: İlk birkaç satırda, çağıran hat hariç hepsi aynı kalması gereken "kaynak plakası" dır getopt
. Program adını sonra değiştirmeli, sonra -n
kısa seçenekler -o
ve sonra uzun seçenekler belirtmelisiniz --long
. Değer alan seçeneklerden sonra iki nokta üst üste koyun.
Son olarak, set
bunun yerine kodu görürseniz eval set
, BSD için yazılmıştır getopt
. Düzenin GNU ile düzgün çalışmadığı halde, eval set
her iki sürümüyle de iyi çalışan stili kullanmak için değiştirmelisiniz .getopt
set
getopt
1 Aslında getopts
içinde ksh93
desteklerin seçenekleri uzun adlandırılmış ama bu kabuk sık olarak kullanılmaz bash
. İçinde zsh
, zparseopts
bu işlevi almak için kullanın .
2 Teknik olarak "GNU getopt
" yanlış adlandırmadır; bu sürüm aslında GNU projesi yerine Linux için yazılmıştır. Bununla birlikte, tüm GNU kurallarını takip eder ve "GNU getopt
" terimi yaygın olarak kullanılır (örneğin, FreeBSD'de).