getopt - getopt

getopt , Unix / POSIX stilinin komut satırı seçeneklerini ayrıştırmak için kullanılan bir C kütüphanesi işlevidir . POSIX belirtiminin bir parçasıdır ve Unix benzeri sistemler için evrenseldir .

Aynı zamanda, kabuk betiklerinde komut satırı argümanlarını ayrıştırmak için bir Unix programının adıdır.

Tarih

Komut satırı programlarıyla ilgili uzun süredir devam eden bir sorun, seçeneklerin nasıl belirleneceğiydi; Erken programları tek karakter seçenekleri (dahil bunu yaparken birçok yol kullanılır -a ), birlikte belirlenen birden fazla seçenekten ( -abc eşdeğerdir için -a -b -c ), çok karakterli seçenekleri ( -inum ), argümanlarla seçenekleri ( -a arg , -inum 3 , -a=arg ) ve farklı önek karakterleri ( -a , +b , /c ).

Getopt fonksiyonu tüm programlar ayrıştırma için kullanabileceği bir standart mekanizma olduğu yazılmıştır komut satırı seçenekleri herkesin bağımlı olabilecek bir ortak arayüz olacağını böylece. Bu nedenle, orijinal yazarlar , tümü bir seçenek dizesi tarafından kontrol edilebilen tek karakter seçeneklerini, birlikte belirtilen birden çok seçeneği ve bağımsız değişkenli seçenekleri ( -a arg veya -aarg ) destekleyen varyasyonlardan seçtiler .

getopt tarihleri en az 1980 ve geri ilk yayınladığı AT & T bunun kamu malı kullanılabilir olması için niyet ile, Dallas, Texas'ta 1985 Uniforum konferansında. Bunun sürümleri daha sonra Unix'in diğer türleri ( 4.3BSD , Linux , vb.) Tarafından toplandı . POSIX.2 standardında unistd.h başlık dosyasının bir parçası olarak belirtilmiştir . Getopt türevleri, birçok programlama dilinin komut satırı seçeneklerini ayrıştırması için oluşturulmuştur .

Uzantılar

getopt , sisteme bağlı bir işlevdir ve davranışı C kütüphanesindeki uygulamaya bağlıdır. Bununla birlikte, gnulib gibi bazı özel uygulamalar mevcuttur.

Geleneksel (POSIX ve BSD) işleme, seçenek olmayan ilk argümanla karşılaşıldığında seçeneklerin sona ermesi ve getopt'un bunu işaret etmek için -1 döndürmesidir. Ancak glibc uzantısında, kullanım kolaylığı açısından seçeneklere her yerde izin verilir ; getopt , bağımsız değişken vektörüne dolaylı olarak izin verir, böylece sonunda seçenek olmayanları bırakmaya devam eder. POSIX zaten -1'i döndürme -- ve onu atlama kuralına sahip olduğundan, onu her zaman taşınabilir bir şekilde seçeneklerin sonu göstergesi olarak kullanabilir.

Bir GNU uzantısı olan getopt_long , bir yerine iki tire ile sunulan daha okunabilir, çok karakterli seçeneklerin ayrıştırılmasına izin verir. İki çizgi seçimi, çoklu --inum karakter seçeneklerinin ( -abc ) birlikte belirtilen tek karakter seçeneklerinden ( ) farklılaştırılmasına olanak tanır . GNU uzantısı da argümanlarla seçenekleri için alternatif bir biçim verir: --name=arg . Bu arayüz popüler oldu ve FreeBSD ve Solaris dahil olmak üzere birçok BSD dağıtımı tarafından kullanıldı (izin verilmeden) . Uzun seçenekleri desteklemenin alternatif bir yolu Solaris ve Korn Shell'de (tercih dizisini genişletme ) görülüyor , ancak bu kadar popüler değildi.

Getopt'un diğer bir yaygın gelişmiş uzantısı, bağımsız değişken çözümlemesinin durumunu sıfırlamaktır; bu, seçenekler-anyware GNU uzantısının ikamesi olarak veya farklı düzeylerde farklı seçeneklerle bir komut satırı arabirimi kümesini "katmanlara ayırmanın" bir yolu olarak kullanışlıdır. Bu, BSD sistemlerinde optreset değişkeni kullanılarak ve GNU sistemlerinde optind değeri 0 olarak ayarlanarak elde edilir.

İçin ortak bir arkadaşı fonksiyonu getopt olduğunu getsubopt . Virgülle ayrılmış alt seçenekler dizisini ayrıştırır.

Kullanım

Kullanıcılar için

Getopt tabanlı programlar için komut satırı sözdizimi, POSIX tarafından önerilen Yardımcı Program Argüman Sözdizimi'dir. Kısacası:

  • Seçenekler, önünde bir - (tire-eksi) karakter bulunan tek karakterli alfanümeriklerdir .
  • Seçenekler, zorunlu veya isteğe bağlı bir argüman alabilir veya hiçbirini alabilir.
  • Bir seçenek bir argüman aldığında, bu aynı jetonda veya bir sonrakinde olabilir. Başka bir deyişle, o bir argüman alırsa -ofoo , ile aynıdır -o foo .
  • Son olmayanlar argüman almadığı sürece birden fazla seçenek birbirine zincirlenebilir. Eğer a ve b ise argüman almaz e isteğe bağlı argüman alır -abe aynıdır -a -b -e , ancak -bea aynı değildir -b -e a önceki kurala bağlı.
  • Tüm seçenekler, seçenek olmayan argümanlardan önce gelir (GNU uzantısı dışında). -- her zaman seçeneklerin sonunu işaretler.

Sözdizimindeki uzantılar arasında GNU kuralı ve Sun'ın CLIP belirtimi bulunur.

Programcılar için

GNU'nun getopt kılavuzu, getopt için böyle bir kullanım belirtir:

#include <unistd.h>

int getopt(int argc, char * const argv[],
           const char *optstring);

Burada argc ve argv , C ana fonksiyon prototipindeki gibi tanımlanır ; yani argc, dizge dizilerinin argv dizisinin uzunluğunu belirtir. SÇNDİZGESİ (dışında normal alphanumerals ne aramak için seçenekleri bir belirtim içeriyor W ) ve ne seçenekler argümanlar (iki nokta üst üste) kabul etmek. Örneğin, "vf :: o:" üç seçeneği ifade eder: bağımsız değişkensiz v , isteğe bağlı bağımsız değişken f ve zorunlu bağımsız değişken o . GNU burada uzun seçenek eş anlamlıları için bir W uzantısı uygular .

getopt'un kendisi, seçenek karakteri veya seçeneklerin sonu için -1 olan bir tamsayı döndürür. Deyim, seçenekler arasında gidip gelmek için bir while döngüsü kullanmak ve seçenekleri seçmek ve uygulamak için bir anahtar-durum ifadesi kullanmaktır. Bu makalenin örnek bölümüne bakın.

Ekstra bilgileri programa geri iletmek için, program extern tarafından bilgi almak için birkaç global değişkene başvurulur getopt :

extern char *optarg;
extern int optind, opterr, optopt;
optarg
Varsa, geçerli seçeneğin argümanına bir işaretçi. Ayrıştırmaya nereden başlayacağınızı kontrol etmek için kullanılabilir (tekrar).
tercih etmek
Nerede getopt şu anda bakıyor argv .
opterr
Getopt öğesinin hata mesajlarını yazdırıp yazdırmayacağını kontrol eden bir boole anahtarı.
optopt
Tanınmayan bir seçenek oluşursa, bu tanınmayan karakterin değeri.

GNU uzantısı getopt_long arabirimi benzerdir, ancak farklı bir başlık dosyasına aittir ve uzun seçeneklerin "kısa" adlarını ve bazı ekstra kontrolleri tanımlamak için fazladan bir seçenek alır. Kısa bir ad tanımlanmamışsa, getopt bunun yerine longindex işaretçisindeki seçenek yapısına başvuran bir dizin koyacaktır .

#include <getopt.h>

int getopt_long(int argc, char * const argv[],
           const char *optstring,
           const struct option *longopts, int *longindex);

Örnekler

POSIX standart getopt kullanarak

#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <unistd.h>    /* for getopt */
int main (int argc, char **argv) {
    int c;
    int digit_optind = 0;
    int aopt = 0, bopt = 0;
    char *copt = 0, *dopt = 0;
    while ((c = getopt(argc, argv, "abc:d:012")) != -1) {
        int this_option_optind = optind ? optind : 1;
        switch (c) {
        case '0':
        case '1':
        case '2':
            if (digit_optind != 0 && digit_optind != this_option_optind)
                printf ("digits occur in two different argv-elements.\n");
            digit_optind = this_option_optind;
            printf ("option %c\n", c);
            break;
        case 'a':
            printf ("option a\n");
            aopt = 1;
            break;
        case 'b':
            printf ("option b\n");
            bopt = 1;
            break;
        case 'c':
            printf ("option c with value '%s'\n", optarg);
            copt = optarg;
            break;
        case 'd':
            printf ("option d with value '%s'\n", optarg);
            dopt = optarg;
            break;
        case '?':
            break;
        default:
            printf ("?? getopt returned character code 0%o ??\n", c);
        }
    }
    if (optind < argc) {
        printf ("non-option ARGV-elements: ");
        while (optind < argc)
            printf ("%s ", argv[optind++]);
        printf ("\n");
    }
    exit (0);
}

GNU uzantısını kullanma getopt_long

#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>    /* for getopt_long; POSIX standard getopt is in unistd.h */
int main (int argc, char **argv) {
    int c;
    int digit_optind = 0;
    int aopt = 0, bopt = 0;
    char *copt = 0, *dopt = 0;
    static struct option long_options[] = {
    /*   NAME       ARGUMENT           FLAG  SHORTNAME */
        {"add",     required_argument, NULL, 0},
        {"append",  no_argument,       NULL, 0},
        {"delete",  required_argument, NULL, 0},
        {"verbose", no_argument,       NULL, 0},
        {"create",  required_argument, NULL, 'c'},
        {"file",    required_argument, NULL, 0},
        {NULL,      0,                 NULL, 0}
    };
    int option_index = 0;
    while ((c = getopt_long(argc, argv, "abc:d:012",
                 long_options, &option_index)) != -1) {
        int this_option_optind = optind ? optind : 1;
        switch (c) {
        case 0:
            printf ("option %s", long_options[option_index].name);
            if (optarg)
                printf (" with arg %s", optarg);
            printf ("\n");
            break;
        case '0':
        case '1':
        case '2':
            if (digit_optind != 0 && digit_optind != this_option_optind)
              printf ("digits occur in two different argv-elements.\n");
            digit_optind = this_option_optind;
            printf ("option %c\n", c);
            break;
        case 'a':
            printf ("option a\n");
            aopt = 1;
            break;
        case 'b':
            printf ("option b\n");
            bopt = 1;
            break;
        case 'c':
            printf ("option c with value '%s'\n", optarg);
            copt = optarg;
            break;
        case 'd':
            printf ("option d with value '%s'\n", optarg);
            dopt = optarg;
            break;
        case '?':
            break;
        default:
            printf ("?? getopt returned character code 0%o ??\n", c);
        }
    }
    if (optind < argc) {
        printf ("non-option ARGV-elements: ");
        while (optind < argc)
            printf ("%s ", argv[optind++]);
        printf ("\n");
    }
    exit (0);
}

Kabukta

Kabuk komut dosyası programcıları genellikle seçenek sağlamak için tutarlı bir yol sağlamak isterler. Bu hedefe ulaşmak için getoptlara dönüyorlar ve bunu kendi dillerine aktarmaya çalışıyorlar.

İlk taşıma denemesi, Unix System Laboratories (USL) tarafından uygulanan getopt programıydı . Bu sürüm, alıntı yapma girişimi göstermediğinden alıntı yapma ve kabuk meta karakterleriyle başa çıkamadı. FreeBSD'ye miras kalmıştır.

1986'da USL, meta karakterler ve boşluklar etrafında güvensiz olmanın artık kabul edilemez olduğuna karar verdi ve bunun yerine Unix SVR3 Bourne Shell için yerleşik getopts komutunu yarattı . Komutu kabuğa oluşturmanın avantajı, artık kabuğun değişkenlerine erişebilmesi ve böylece değerlerin alıntı yapılmadan güvenli bir şekilde yazılabilmesidir. Mevcut ve bağımsız değişken konumlarının, OPTIND ve OPTARG konumlarını izlemek için kabuğun kendi değişkenlerini kullanır ve seçenek adını bir kabuk değişkeninde döndürür.

1995 yılında getopts dahil edilmiştir Tek UNIX Şartname sürüm 1 / X / Open Taşınabilirlik Kuralları Şimdi Sayı 4. POSIX Kabuk standardının bir parçası getopt POSIX uyumlu olmaya çalışıyorum diğer birçok kabuklarda Çok uzaklara yayıldı.

getopt temelde, util- linux'un eski getopt'un tüm sorunlarını kaçarak çözen gelişmiş bir sürümü çıkana kadar unutuldu . Ayrıca GNU'nun uzun seçenek adlarını da destekler. Öte yandan, uzun seçenekler getopts diğer kabuklarda komutta nadiren uygulanmıştır , ksh93 bir istisnadır.

Diğer dillerde

getopt , ortak POSIX komut argüman yapısının kısa bir açıklamasıdır ve hem kendilerine hem de komut satırındaki kullanıcıya benzer bir arayüz sağlamak isteyen programcılar tarafından geniş çapta çoğaltılır.

  • C: POSIX olmayan sistemler getopt C kitaplığında gönderilmez, ancak işlevselliği sağlamak için gnulib ve MinGW (ikisi de GNU stilini kabul eder) ve bazı daha minimal kitaplıklar kullanılabilir. Alternatif arayüzler de mevcuttur:
    • popt Tarafından kullanılan kütüphane, RPM paket yöneticisi olma avantajı vardır girintili .
    • argp Glibc'nin ve gnulib içinde fonksiyonların ailesi biraz daha kolaylık ve modülerlik sağlar.
  • D: D programlama dilinin standart kitaplıkta bir getopt modülü vardır.
  • Go : flag uzun bayrak isimlerine izin veren paket ile birlikte gelir . getopt Paket destekler yakın C işlev işlem. getopt Orijinal POSIX'e çok daha yakın bir arayüz sağlayan başka bir paket de var .
  • Haskell : Esasen GNU getopt kütüphanesinin bir Haskell portu olan System.Console.GetOpt ile birlikte gelir.
  • Java: Java standart kitaplığında getopt uygulaması yoktur. GNU getopt'tan taşınan gnu.getopt.Getopt ve Apache Commons CLI dahil olmak üzere birkaç açık kaynak modülü mevcuttur .
  • Lisp : Ortak bir standart kitaplığı olmayan birçok farklı lehçeye sahiptir. Lisp'in bazı lehçeleri için bazı üçüncü parti getopt uygulamaları vardır. Common Lisp , önemli bir üçüncü taraf uygulamasına sahiptir.
  • Free Pascal : GetOpts adlı standart birimlerinden biri olarak kendi uygulamasına sahiptir. Tüm platformlarda desteklenmektedir.
  • Perl programlama dili : standart kitaplığında getopt'un iki ayrı türevi vardır: Getopt :: Long ve Getopt :: Std.
  • PHP : getopt () işlevine sahiptir.
  • Python : standart kitaplığında C'nin getopt ve GNU uzantılarına dayalı bir modül içerir . Python'un standart kitaplığı, kullanımı daha uygun seçenekleri ayrıştırmak için başka modüller de içerir.
  • Ruby: standart kitaplığı GetoptLong'da getopt_long uygulamasına sahiptir. Ruby ayrıca standart kitaplığında daha sofistike ve kullanışlı bir arayüze sahip modüllere sahiptir. Orijinal getopt arayüzünün üçüncü taraf uygulaması mevcuttur.
  • .NET Framework : standart kitaplığında getopt işlevine sahip değildir. Üçüncü taraf uygulamaları mevcuttur.

Referanslar

Dış bağlantılar