getopty

getopty
Deweloperzy Różni programiści open source i komercyjni
Pierwsze wydanie 1986 ; 37 lat temu ( 1986 )
System operacyjny Unix , uniksopodobny , IBM i
Typ Komenda

getopts to wbudowane polecenie powłoki systemu Unix do analizowania argumentów wiersza poleceń . Został zaprojektowany do przetwarzania argumentów wiersza poleceń, które są zgodne z wytycznymi dotyczącymi składni narzędzia POSIX, opartymi na interfejsie C getopt .

Poprzednikiem getopts był zewnętrzny program getopt firmy Unix System Laboratories .

Historia

Oryginalny getopt miał kilka problemów: nie mógł obsługiwać białych znaków lub metaznaków powłoki w argumentach i nie było możliwości wyłączenia wyjścia komunikatów o błędach.

getopts został po raz pierwszy wprowadzony w 1986 roku w powłoce Bourne dostarczanej z Unixem SVR3. Używa własnych zmiennych powłoki do śledzenia pozycji bieżących i pozycji argumentów, OPTIND i OPTARG , i zwraca nazwę opcji w zmiennej powłoki. Wcześniejsze wersje powłoki Bourne'a nie miały getopts .

W 1995 getopts został włączony do specyfikacji Single UNIX w wersji 1 / X/Open Portability Guidelines, wydanie 4. W rezultacie getopts jest teraz dostępny w powłokach, w tym Bourne Shell , KornShell , Almquist shell , Bash i Zsh .

Komenda getopts została również przeniesiona do systemu operacyjnego IBM i .

Nowoczesne użycie getopt zostało częściowo przywrócone, głównie dzięki ulepszonej implementacji w util-linux . Ta wersja, oparta na BSD getopt , nie tylko naprawiła dwie skargi dotyczące starego getopt , ale także wprowadziła możliwość analizowania długich opcji w stylu GNU i opcjonalnych argumentów opcji, funkcji, których brakuje getopts . Jednak różne dystrybucje BSD trzymały się starej implementacji.

Stosowanie

Streszczenie użycia getopt i getopts jest podobne do rodzeństwa C :

    getopt  optstring  [parametry]  getopts  optstring  nazwa_zmiennej  [parametry] 
  • Część optstring ma taki sam format jak rodzeństwo C.
  • parametrów po prostu akceptuje wszystko , co chce przeanalizować getopt. Wspólną wartością są wszystkie parametry „$@” w powłoce POSIX.
    • Ta wartość istnieje w getopts, ale jest rzadko używana, ponieważ może po prostu uzyskać dostęp do parametrów powłoki. Jest to jednak przydatne przy resetowaniu parsera.
  • Część varname getopts nazywa zmienną powłoki, w której przechowywana jest przeanalizowana opcja.

Sposób korzystania z poleceń jest jednak bardzo różny:

  • getopt po prostu zwraca płaski ciąg zawierający tokeny oddzielone spacjami reprezentujące „znormalizowany” argument. Następnie używa się pętli while, aby przeanalizować ją natywnie.
  • getopts ma być wielokrotnie wywoływany, tak jak getopt w C. Kiedy trafi na koniec argumentów, zwraca 1 (powłoka fałsz).

Ulepszenia

W różnych getoptach

Wiosną 2004 (rozwój wersji beta Solarisa 10) implementacja libc getopt() została udoskonalona w celu obsługi długich opcji. W rezultacie ta nowa funkcja była również dostępna we wbudowanych komendach getopt Bourne Shell. Jest to wyzwalane przez sufiksy w nawiasach w ciągu optstring określające długie aliasy.

KornShell , jak i Zsh mają rozszerzenie dla długich argumentów. Pierwsza jest zdefiniowana jak w Solarisie, druga jest realizowana za pomocą osobnego zparseopts .

KornShell dodatkowo implementuje rozszerzenia optstring dla opcji zaczynających się od + zamiast - .

W Linuksie getopt

Alternatywą dla getopts jest udoskonalona dla Linuksa wersja getopt , zewnętrznego programu wiersza poleceń.

Ulepszona wersja getopt dla Linuksa ma dodatkowe bezpieczeństwo getopts oraz bardziej zaawansowane funkcje. Obsługuje długie nazwy opcji (np. --help ) i opcje nie muszą występować przed wszystkimi operandami (np. komenda operand1 operand2 -a operand3 -b jest dozwolona przez rozszerzoną wersję getopt w Linuksie, ale nie działa z getopts ). Obsługuje również metaznaki ucieczki dla powłok (takich jak tcsh i POSIX sh) oraz opcjonalne argumenty.

Porównanie

Program
Funkcja
Getopty POSIX Getopty Solarisa Getopt Unix/BSD Pobierz Linuksa
Dzieli opcje dla łatwego analizowania Tak Tak Tak Tak
Umożliwia pomijanie komunikatów o błędach Tak Tak NIE Tak
Bezpieczny ze spacjami i metaznakami Tak Tak NIE Tak
Umożliwia mieszanie operandów z opcjami NIE Tak NIE Tak
Obsługuje długie opcje Współzawodnictwo Tak NIE Tak
Argumenty opcjonalne Obsługa błędów Obsługa błędów NIE Tak

Przykłady

Załóżmy, że budujemy program do pobierania Wikipedii w bash, który przyjmuje trzy opcje i zero dodatkowych argumentów:

 wpdown -a  nazwa artykułu  -l  [język]  -v 

Jeśli to możliwe, dopuszczamy następujące długie argumenty:

-a --artykuł -l --język, --lang -v --pełny

Dla jasności nie ma tekstu pomocy i zakładamy, że istnieje program, który pobiera dowolną stronę internetową. Ponadto wszystkie programy mają postać:


0



  
    
    


  
     


   
    
   
 #!/bin/bash  VERBOSE  =  ARTYKUŁ  =  ''  LANG  =  en  # [PRZYKŁAD TUTAJ]  if  ((  VERBOSE >  2  ))  ;  następnie  printf  '%s\n'  'Argumenty nie będące opcjami:'  printf  '%q '  "  ${  pozostały  [@]]  }  "  fi  if  ((  VERBOSE >  1  ))  ;  następnie  printf  'Pobieranie %s:%s\n'  "  $LANG  "  "  $ARTICLE  "  fi  if  [[  !  $ARTICLE  ]]  ;  następnie  printf  '%s\n'  "Brak artykułów!"  >  &  2  wyjście  1  fi  save_webpage  "https://  ${  LANG  }  .wikipedia.org/wiki/  ${  ARTYKUŁ  }  " 

Używanie starego getopt

Stary getopt nie obsługuje opcjonalnych argumentów:


   



 
      
         
           
           
      
                      
    


 # przeanalizuj wszystko; jeśli to się nie powiedzie, zwalniamy   args  =  `  getopt  'a:l:v'  $*  `  ||  wyjdź  # teraz mamy oczyszczone argumenty... zamień na nie oryginał set  --  $  args  while  true  ;  zrób  case  $1  in  (  -v  )  ((  VERBOSE++  ))  ;  zmiana  ;;  (  -a  )  ARTYKUŁ  =  2 $  ;  zmiana  2  ;;  (  -l  )  JĘZYK  =  $2  ;  zmiana  2  ;;  (  -  )  przesunięcie  ;  przerwa  ;;  (  *  )  wyjście  1  ;;  # error  esac  done  pozostało  =(  "  $@  "  ) 

Ten skrypt zerwie również z każdym tytułem artykułu zawierającym spację lub metaznak powłoki (jak ? lub *).

Za pomocą getoptów

Getopty nadają skryptowi wygląd i działanie interfejsu C, chociaż w POSIX nadal nie ma opcjonalnych argumentów:


   
      
         
         
         
         
              
                 
                    
            
    


 
 #!/bin/sh  while  getopts  ':a:l:v'  opt  ;  wykonaj  case  $opt  in  (  v  )  ((  VERBOSE++  ))  ;;  (  a  )  ARTYKUŁ  =  $OPTARG  ;;  (  l  )  JĘZYK  =  $OPTARG  ;;  (  :  )  # "argumenty opcjonalne" (brak obsługi argumentów opcji)  case  $OPTARG  in  (  a  )  wyjście  1  ;;  # błąd, zgodnie z naszą składnią  (  l  )  :  ;;  # akceptowalne, ale nic nie robi  esac  ;;  esac  done  shift  "  $OPTIND  "  # pozostało "$@" 

Ponieważ nie operujemy już bezpośrednio na opcjach powłoki, nie musimy już ich zmieniać. Jednak operacja dzielenia jest wymagana, aby teraz uzyskać pozostałe argumenty.

Jest możliwe, ale żmudne naśladowanie obsługi długich argumentów przez traktowanie --fast jako argumentu fast dla opcji - .

Korzystanie z getopt w Linuksie

Linux getopt pomija swoje wyjście i potrzebne jest polecenie „eval”, aby powłoka je zinterpretowała. Reszta bez zmian:


  
 

 
      
      
            
      
              
      
            
               
              
            
             
      
                     
    


 # Używamy „$@” zamiast $*, aby zachować informacje o granicach argumentów  ARGS  =  $(  getopt -o  'a:l::v'  --long  'article:,language::,lang::,verbose'  - -  "  $@  "  )  ||  wyjdź  eval  "set --  $ARGS  "  podczas gdy  prawda  ;  wykonaj  przypadek  $1  in  (  -v  |  --verbose  )  ((  VERBOSE++  ))  ;  zmiana  ;;  (  -a  |  --artykuł  )  ARTYKUŁ  =  $2  ;  zmiana  2  ;;  (  -l  |  --lang  |  --language  )  # uchwyt opcjonalny: getopt normalizuje go do pustego łańcucha  if  [  -n  "  ​​$2  "  ]  ;  wtedy  LANG  =  2 $  fi  shift  2  ;;  (  -  )  przesunięcie  ;  przerwa  ;;  (  *  )  wyjście  1  ;;  # error  esac  done  pozostało  =(  "  $@  "  ) 

Zobacz też

Linki zewnętrzne