getopt
Getopt är en C- biblioteksfunktion som används för att analysera kommandoradsalternativ för Unix/POSIX-stilen. Det är en del av POSIX- specifikationen och är universell för Unix-liknande system. Det är också namnet på ett Unix-program för att analysera kommandoradsargument i skalskript.
Historia
Ett långvarigt problem med kommandoradsprogram var hur man anger alternativ; tidiga program använde många sätt att göra det på, inklusive alternativ för enstaka tecken ( -a
), flera alternativ specificerade tillsammans ( -abc
motsvarar -a -b -c
), alternativ med flera tecken ( -inum
), alternativ med argument ( -a arg
, -inum 3
, -a=arg
), och olika prefixtecken ( -a
, +b
, /c
).
Getopt - funktionen skrevs för att vara en standardmekanism som alla program kunde använda för att analysera kommandoradsalternativ så att det skulle finnas ett gemensamt gränssnitt som alla kunde lita på. Som sådan valde de ursprungliga författarna ut ur varianterna stöd för alternativ för enstaka tecken, flera alternativ specificerade tillsammans och alternativ med argument ( -a arg
eller -aarg
), alla styrbara av en alternativsträng.
getopt går tillbaka till åtminstone 1980 och publicerades först av AT&T vid UNIFORUM-konferensen 1985 i Dallas, Texas, med avsikten att den skulle vara tillgänglig för allmänheten. [ citat behövs ] Versioner av det plockades senare upp av andra varianter av Unix ( 4.3BSD , Linux , etc.). Det är specificerat i POSIX.2 -standarden som en del av unistd.h- huvudfilen . Derivat av getopt har skapats för många programmeringsspråk för att analysera kommandoradsalternativ.
Tillägg
getopt är en systemberoende funktion och dess beteende beror på implementeringen i C-biblioteket. Vissa anpassade implementeringar som gnulib är dock tillgängliga.
Den konventionella (POSIX och BSD) hanteringen är att alternativen slutar när det första icke-alternativargumentet påträffas, och att getopt skulle returnera -1 för att signalera det. I glibc är dock alternativ tillåtna var som helst för att underlätta användningen; getopt permuterar implicit argumentvektorn så att den fortfarande lämnar icke-alternativen till slut. Eftersom POSIX redan har konventionen att returnera -1 på --
och hoppa över den, kan man alltid portabelt använda den som en slut-på-alternativ-signifier.
En GNU- tillägg, getopt_long , tillåter analys av mer läsbara flerteckenalternativ, som introduceras med två streck istället för ett. Valet av två bindestreck gör att alternativ för flera tecken ( --inum
) kan skiljas från alternativ för enstaka tecken som specificeras tillsammans ( -abc )
. GNU-tillägget tillåter också ett alternativt format för alternativ med argument: --name=arg
. Detta gränssnitt visade sig populärt och har tagits upp (utan permutationen) av många BSD-distributioner inklusive FreeBSD såväl som Solaris . Ett alternativt sätt att stödja långa alternativ finns i Solaris och Korn Shell (förlänger optstring ) , men det var inte lika populärt.
En annan vanlig avancerad förlängning av getopt är att återställa tillståndet för argumentanalys; detta är användbart som en ersättning av options-anyware GNU-tillägget, eller som ett sätt att "lägga" en uppsättning kommandoradsgränssnitt med olika alternativ på olika nivåer. Detta uppnås i BSD-system som använder en optreset- variabel och på GNU-system genom att sätta optind till 0.
En vanlig komplementfunktion till getopt
är getsubopt
. Den analyserar en sträng av kommaseparerade underalternativ.
Användande
För användare
Kommandoradssyntaxerna för getopt-baserade program är den POSIX-rekommenderade Utility Argument Syntax. Kortfattat:
- Alternativen är enstaka tecken som föregås av ett
-
(bindestreck-minus). - Alternativ kan ha ett argument, obligatoriskt eller valfritt, eller inget.
- För att ange att ett alternativ tar ett argument, inkludera
:
efter alternativnamnet (endast under den initiala specifikationen) - När ett alternativ tar ett argument kan detta vara i samma token eller i nästa. Med andra ord, om
o
tar ett argument, är-ofoo
detsamma som-o foo
. - Flera alternativ kan kedjas samman, så länge som de icke-sista inte tar argument. Om
a
ochb
inte tar några argument medane
tar ett valfritt argument, är-abe
detsamma som-a -b -e
, men-bea
är inte detsamma som-b -ea
på grund av föregående regel. - Alla alternativ föregår icke-alternativargument (förutom i GNU-tillägget).
--
markerar alltid slutet på alternativen.
Tillägg på syntaxen inkluderar GNU-konventionen och Suns CLIP -specifikation.
För programmerare
Getopt-manualen från GNU specificerar en sådan användning för getopt:
#include <unistd.h> int getopt ( int argc , char * const argv [], const char * optstring );
Här definieras argc och argv exakt som de är i prototypen för C- huvudfunktionen ; dvs argc indikerar längden på argv-array-of-strings. Opt -strängen innehåller en specifikation av vilka alternativ man ska leta efter (normala alfanumeriska siffror förutom W ), och vilka alternativ man ska acceptera argument (kolon). Till exempel "vf::o:" till tre alternativ: ett argumentlöst v , ett valfritt-argument f och ett obligatoriskt-argument o . GNU implementerar här en W -tillägg för långa alternativsynonymer.
getopt själv returnerar ett heltal som antingen är ett alternativtecken eller -1 för slutet av alternativen. Formspråket är att använda en while-loop för att gå igenom alternativ, och att använda en switch-case-sats för att välja och agera på alternativ. Se exempelavsnittet i den här artikeln.
, refereras till några globala externa variabler av programmet för att hämta information från
getopt
:
extern char * optarg ; extern int optind , opterr , optopt ;
- optarg
- En pekare till argumentet för det aktuella alternativet, om det finns. Kan användas för att styra var man ska börja tolka (igen).
- optind
- Där getopt för närvarande tittar på i argv .
- opterr
- En boolesk omkopplare som styr om getopt ska skriva ut felmeddelanden.
- optopt
- Om ett oigenkänt alternativ inträffar, värdet av det okända tecknet.
GNU-tillägget getopt_long- gränssnittet är liknande, även om det tillhör en annan rubrikfil och tar ett extra alternativ för att definiera de "korta" namnen på långa alternativ och några extra kontroller. Om ett kort namn inte är definierat, kommer getopt att placera ett index som refererar till alternativstrukturen i longindex- pekaren istället.
#include <getopt.h> int getopt_long ( int argc , char * const argv [], const char * optstring , const struct option * longopts , int * longindex );
Exempel
Använder POSIX standard getopt
0
0 0
0 0
0
0
#include <stdio.h> /* för printf */ #include <stdlib.h> /* för exit */ #include <unistd.h> /* för getopt */ int main ( int argc , char ** argv ) { int c ; int siffra_optind = ; int aopt = , bopt = ; char * copt = , * dopt = ; 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 != && digit_optind != this_option_optind ) { printf ( "siffror förekommer i två olika argv-element. \n " ); } digit_optind = this_option_optind ; printf ( "alternativ %c \n " , c ); bryta ; case 'a' : printf ( "alternativ a \n " ); aopt = 1 ; bryta ; case 'b' : printf ( "alternativ b \n " ); bopt = 1 ; bryta ; case 'c' : printf ( "alternativ c med värdet '%s' \n " , optarg ); copt = optarg ; bryta ; case 'd' : printf ( "alternativ d med värdet '%s' \n " , optarg ); dopt = optarg ; bryta ; fall '?' : bryta ; default : printf ( "?? getopt returnerade teckenkod 0%o ?? \n " , c ); } } if ( optind < argc ) { printf ( "icke-alternativ ARGV-element: " ); while ( optind < argc ) { printf ( "%s" , argv [ optind ++ ]); } printf ( " \n " ); } avsluta ( ); }
Använder GNU-tillägget getopt_long
0
0 0
0 0
0
0
0
0
0
0 0
0
0
0
0
#include <stdio.h> /* för printf */ #include <stdlib.h> /* för exit */ #include <getopt.h> /* för getopt_long; POSIX standard getopt är i unistd.h */ int main ( int argc , char ** argv ) { int c ; int siffra_optind = ; int aopt = , bopt = ; char * copt = , * dopt = ; static struct option long_options [] = { /* NAMN ARGUMENT FLAGGA SHORTNAME */ { "add" , required_argument , NULL , }, { "append" , no_argument , NULL , }, { "delete" , required_argument , NULL , } , "verbose" , no_argument , NULL , }, { "create" , required_argument , NULL , 'c' }, { "file" , required_argument , NULL , }, { NULL , , NULL , } }; int option_index = ; while (( c = getopt_long ( argc , argv , "abc:d:012" , long_options & option_index ) ) != -1 ) { int this_option_optind = optind ? optind : 1 ; switch ( c ) { case : printf ( "alternativ %s" , long_options [ option_index ]. namn ); if ( optarg ) { printf ( " med arg %s " , optarg ); } printf ( " \n " ); bryta ; case '0' : case '1' : case '2' : if ( digit_optind != && digit_optind != this_option_optind ) { printf ( "siffror förekommer i två olika argv-element. \n " ); } digit_optind = this_option_optind ; printf ( "alternativ %c \n " , c ); bryta ; case 'a' : printf ( "alternativ a \n " ); aopt = 1 ; bryta ; case 'b' : printf ( "alternativ b \n " ); bopt = 1 ; bryta ; case 'c' : printf ( "alternativ c med värdet '%s' \n " , optarg ); copt = optarg ; bryta ; case 'd' : printf ( "alternativ d med värdet '%s' \n " , optarg ); dopt = optarg ; bryta ; fall '?' : bryta ; default : printf ( "?? getopt returnerade teckenkod 0%o ?? \n " , c ); } } if ( optind < argc ) { printf ( "icke-alternativ ARGV-element: " ); while ( optind < argc ) { printf ( "%s" , argv [ optind ++ ]); } printf ( " \n " ); } avsluta ( ); }
I Shell
Shell-skriptprogrammerare vill vanligtvis tillhandahålla ett konsekvent sätt att tillhandahålla alternativ. För att uppnå detta mål vänder de sig till getopts och försöker överföra det till sitt eget språk.
Det första försöket med portering var programmet getopt , implementerat av Unix System Laboratories (USL). Den här versionen kunde inte hantera citering och skalmetatecken, eftersom den inte visar några försök att citera. Det har ärvts till FreeBSD.
1986 beslutade USL att det inte längre var acceptabelt att vara osäker kring metatecken och blanksteg, och de skapade det inbyggda kommandot getopts för Unix SVR3 Bourne Shell istället. Fördelen med att bygga in kommandot i skalet är att det nu har tillgång till skalets variabler, så värden kan skrivas säkert utan citat. Den använder skalets egna variabler för att spåra positionen för nuvarande och argumentpositioner, OPTIND och OPTARG , och returnerar alternativnamnet i en skalvariabel.
1995 inkluderades getopts i
Single UNIX-specifikationen version 1/ X/Open Portability Guidelines Issue 4. Nu en del av POSIX Shell-standarden har getopts spridit sig långt och brett i många andra skal för att försöka vara POSIX-kompatibla.
getopt glömdes i princip bort tills util-linux kom ut med en förbättrad version som fixade alla gamla getopts problem genom att escape. Den stöder också GNU:s långa alternativnamn. Å andra sidan har långa alternativ implementerats sällan i getopts
i andra skal, ksh93 är ett undantag.
På andra språk
getopt är en kortfattad beskrivning av den vanliga POSIX-kommandoargumentstrukturen, och den replikeras brett av programmerare som försöker tillhandahålla ett liknande gränssnitt, både till sig själva och till användaren på kommandoraden.
- C: icke-POSIX-system skickar inte
getopt
i C-biblioteket, men gnulib och MinGW (båda accepterar GNU-stil), såväl som några mer minimala bibliotek, kan användas för att tillhandahålla funktionaliteten. Alternativa gränssnitt finns också:- Popt
-
biblioteket, som används av RPM-pakethanteraren , har den ytterligare fördelen att vara återkommande . - Arp
-
familjen av funktioner i glibc och gnulib ger lite mer bekvämlighet och modularitet.
- Popt
- D-programmeringsspråk : har getopt-modul i D-standardbiblioteket.
-
Go : kommer med
flaggpaketet
, som tillåter långa flaggnamn. Getopt-
paketet stöder bearbetning närmare C-funktionen. Det finns också ett annatgetopt
-paket som ger gränssnittet mycket närmare den ursprungliga POSIX-en. - Haskell : kommer med System.Console.GetOpt, som i huvudsak är en Haskell-port i GNU getopt-biblioteket.
- Java : Det finns ingen implementering av getopt i Java-standardbiblioteket. Det finns flera moduler med öppen källkod, inklusive gnu.getopt.Getopt, som porteras från GNU getopt, och Apache Commons CLI.
- Lisp : har många olika dialekter utan något gemensamt standardbibliotek. Det finns några tredjepartsimplementeringar av getopt för vissa dialekter av Lisp. Common Lisp har en framstående implementering från tredje part.
- Free Pascal : har sin egen implementering som en av sina standardenheter som heter GetOpts. Det stöds på alla plattformar.
- Perl programmeringsspråk : har två separata derivator av getopt i sitt standardbibliotek: Getopt::Long och Getopt::Std.
- PHP : har en getopt-funktion.
- Python : innehåller en modul i sitt standardbibliotek baserad på C:s getopt och GNU-tillägg. Pythons standardbibliotek innehåller även andra moduler för att analysera alternativ som är mer bekväma att använda.
- Ruby : har en implementering av getopt_long i sitt standardbibliotek, GetoptLong. Ruby har också moduler i sitt standardbibliotek med ett mer sofistikerat och bekvämt gränssnitt. En tredje parts implementering av det ursprungliga getopt-gränssnittet är tillgängligt.
- .NET Framework : har inte getopt-funktionalitet i sitt standardbibliotek. Tredjepartsimplementeringar är tillgängliga.
externa länkar
- POSIX-specifikation
- GNU getopt manual
- Full getopt-port för Unicode och Multibyte Microsoft Visual C, C++ eller MFC-projekt