2014-04-07 15 views
5

Jestem całkiem nowym użytkownikiem skryptów Ubuntu i Bash i chciałem wiedzieć, dlaczego mogę uzyskać ten błąd podczas korzystania z GETOPTS.nowość w Bash - wciąż pojawia się błąd opcji nielegalnej

Oto kod, którego używam, aby go uruchomić.

Myślę, że poprawnie wywołuję skrypt i powinien on wyszukiwać termin, który wpisuję jako wyszukiwany termin za pomocą grap. ale z jakiegoś powodu tak nie jest. Wszelkie rady dotyczące tego, co mogę zrobić jako ogólną zasadę podczas pracy z grep również byłyby mile widziane, dziękuję.

#!/bin/bash 

valid=0 
file_arg="" 
display_help="" 
column="" 
pattern="" 

while getopts f:d:s:m: opt 
do 
    case "$opt" in 
     d) display_help=$OPTARG 
      ;; 
     f) file_arg=$OPTARG 
      ;; 
     c) column=$OPTARG 
      ;; 
     p) pattern=$OPTARG 
      ;; 
     *) valid=1 
      break 
      ;; 
    esac 
done 

if [ $valid -eq "0" ] 
then 
    if [ $pattern != "" ] 
    then 
     cat $file_arg | grep $pattern 
    else 
     cat $file 
    fi 
else 
    echo -n "Usage: FILE -f <name> | COLUMN -> -c <name> | HELP -> -d | PATTERN -> -p <expression>" 
fi 

Odpowiedz

10

W getopts nie określił p opcję masz tylko f:d:s:m: opcje.

Myślę, że masz na myśli p zamiast m lub odwrotnie.

Należy f:d:s:m:p: lub f:d:s:p:

+0

Dzięki za człowiek, bardzo doceniamy! – Duenna

+0

@Duenna, serdecznie zapraszamy. –

2

Istnieje kilka innych problemów ze skryptu, jak wspomniano Jayesh, trzeba uwzględnić wszystkie parametry getopt ale trzeba także uważać z porównań łańcuchowych, oto kilka więcej poprawek z sugestiami:

(Patrz http://www.tldp.org/LDP/abs/html/comparison-ops.html informacji dla porównania ciąg)

#!/bin/bash 

# switch around valid, convention is 1 == true and 0 == false 
valid=1 
file_arg="" 
display_help="" 
column="" 
pattern="" 

# getopt patterns need to match following case statement 
while getopts f:d:c:p: opt; 
do 
    case $opt in 
     d) display_help=$OPTARG 
      ;; 
     f) file_arg=$OPTARG 
      ;; 
     c) column=$OPTARG 
      ;; 
     p) pattern=$OPTARG 
      ;; 
     *) valid=0 
      break 
      ;; 
    esac 
done 

# changed value to reflect true false convention 
if [ "$valid" -eq "1" ] 
then 
    # string comparison in bash should be done using specific operators 
    if [ -n "$pattern" ] 
    then 
     cat $file_arg | grep $pattern 
    else 
     # typo, this should be file_arg? 
     cat $file_arg 
    fi 
else 
    echo -n "Usage: FILE -f <name> | COLUMN -> -c <name> | HELP -> -d | PATTERN -> -p <expression>" 
fi 
3

należy również rozważyć możliwości Supression błędów i obsługa błędów z getopts.

Jeśli pierwszy znak łańcucha opcji jest dwukropek (:) następnie getopts nie będzie raportować błędy i zamiast zapewni środki przenoszenia samemu błędów. Dwa dodatkowe znaki mogą być następnie wykorzystane w Twoim przypadku warunkowego użytkowania:

  • ? Jeśli opcja zostanie wprowadzony niepoprawny następnie $opt zostanie ustawiona na ? i $OPTARG odbędzie się nieprawidłowy znak, np jeśli użyto -z, którego nie ma w łańcuchu opcji, to $OPTARG zostanie ustawione na z.

  • : Jeżeli wymagany dodatkowy argument zostanie pominięty przez użytkownika następnie $opt zostanie ustawiony na : i $OPTARG będzie posiadać charakter polecenia, na przykład jeśli zamiast -p arg został użyty -p, wówczas $OPTARG zostanie ustawiony na p.

Jeśli zostanie to zaimplementowane, wówczas catch-all * stanie się zbędny i powinien zostać usunięty. Uwaga: jeśli zostawisz to i będzie powyżej ? lub :, będziesz proszony o problemy. Upewnij się także, że numer ? został usunięty, tak jak to \?).

Mam nadzieję, że to pomoże.

# Note the addition of the inital colon before 'f'. 
while getopts :f:d:c:p: opt; 
do 
    case $opt in 
     d) display_help=$OPTARG 
      ;; 
     f) file_arg=$OPTARG 
      ;; 
     c) column=$OPTARG 
      ;; 
     p) pattern=$OPTARG 
      ;; 

     # Option error handling. 

     \?) valid=0 
      echo "An invalid option has been entered: $OPTARG" 
      ;; 

     :) valid=0 
      echo "The additional argument for option $OPTARG was omitted." 
      ;; 

     # This is now redundant: 
     # *) valid=0 
     #  break 
     #  ;; 
    esac 
done 
+1

Jeśli '?' Nie jest zmienione, to pasuje do czegokolwiek i nigdy nie dojdziesz do przypadku ':', więc brakujące argumenty są zgłaszane jako nieprawidłowe opcje. –

+0

Dzięki za wyjaśnienie Mark. Przydatna wiedza. – mattst

Powiązane problemy