2010-04-15 5 views
18

Es gibt eine Reihe von Fragen über diese Art von Sache, aber stellen Sie sich vor, wir zielen auf ein generisches Linux-System mit getopt und getopts installiert (nicht, dass wir beide verwenden werden, aber sie scheinen populär)Shell Skriptargument Parsing

Wie analysieren wir beide lange (--example | --example einfach Option) und kurze argruments (-e | -esimple-Beispiel | -es simple-Beispiel)

Antwort

33

Sie wollen getopt mit langen verwenden und kurze Optionen. Ein Beispiel von Arbeitscode:

# Parse arguments 
TEMP=$(getopt -n $PROGRAM_NAME -o p:P:cCkhnvVS \ 
--long domain-password:,pop3-password:\   
,create,cron,kill,help,no-sync-passwords,version,verbose,skip-pop3 \ 
-- "[email protected]")                

# Die if they fat finger arguments, this program will be run as root 
[ $? = 0 ] || die "Error parsing arguments. Try $PROGRAM_NAME --help"  

eval set -- "$TEMP" 
while true; do  
     case $1 in 
       -c|--create) 
         MODE="CREATE"; shift; continue 
       ;;          
       -C|--cron)        
         MODE="CRON"; shift; continue 
       ;;          
       -k|--kill)        
         MODE="KILL"; shift; continue 
       ;;          
       -h|--help)        
         usage       
         exit 0       
       ;;          
       -n|--no-sync-passwords)    
         SYNC_VHOST=0; shift; continue 
       ;;          
       -p|--domain-password)     
         DOMAIN_PASS="$2"; shift; shift; continue 
       ;;            
       -P|--pop3-password)        
         POP3_PASS="$2"; shift; shift; continue 
       ;;            
       -v|--version)         
         printf "%s, version %s\n" "$PROGRAM_NAME" "$PROGRAM_VERSION" 
         exit 0              
       ;;                 
       -v|--verbose)              
         VERBOSE=1; shift; continue         
       ;;                 
       -S|--skip-pop3)              
         SKIP_POP=1; shift; continue         
       ;;                 
       --)                 
         # no more arguments to parse         
         break              
       ;;                 
       *)                 
         printf "Unknown option %s\n" "$1"       
         exit 1              
       ;;                 
     esac                   
done  

Hinweis, die ist eine Funktion, die vorher definiert wurde (nicht gezeigt).

Die Option -n teilt Getopt mit, Fehler als den Namen meines Programms zu melden, nicht als getopt. -o definiert eine Liste von kurzen Optionen (:, nachdem eine Option ein benötigtes Argument anzeigt) und --long gibt die Liste der langen Optionen an (entsprechend den kurzen Optionen).

Der Rest ist nur ein einfacher Schalter, der shift entsprechend aufruft, um den Argumentzeiger vorzurücken. Beachten Sie, shift; shift; ist nur eine harte Gewohnheit. In der heutigen modernen Welt würde wahrscheinlich shift 2 ausreichen.

Der moderne getopt ist über neuere Plattformen ziemlich konsistent, jedoch können auf älteren (etwa vor Redhat 9) Systemen Probleme mit der Portabilität auftreten. Informationen zur Abwärtskompatibilität finden Sie unter man getopt. Es ist jedoch unwahrscheinlich, dass Sie darauf stoßen werden.

Schließlich, nach Optionen Parsen, können Sie einmal wieder anrufen:

eval set -- "[email protected]" 

Dies wird das Argument Zeiger auf etwas anderes links auf der Kommandozeile bewegen, nachdem getopt Optionen getan wurde Parsen. Sie können dann nur noch shift lesen. Zum Beispiel sah, wenn ein Befehl wie folgt aus:

./foo --option bar file1.txt file2.txt file3.txt 

Vergessen Sie nicht, eine handliche -h/--help Option machen Sie Ihre neue Phantasie Optionen zu drucken, sobald Sie fertig sind. :) Wenn Sie diese Ausgabe help2man freundlich machen, haben Sie eine sofortige Manpage für Ihr neues Tool.

bearbeiten

Bei den meisten Distributionen können Sie weiteres Beispiel getopt Code in /usr/share/doc/util-linux/examples finden, die standardmäßig installiert werden sollte.

+0

Ich stelle fest, dass ich hier keine Vernunft mache, um nach mehreren Befehlen zu suchen, die MODE setzen. In diesem Fall war es akzeptabel, dass die letzte Option einfach Vorrang hatte, und die Paste war nur dazu gedacht, Informationen über eine Art der Verwendung von "getopt" zu geben. –

+0

Ich wurde schon mehrfach mit 'getopt()' angesprochen. Nenn mich dumm, aber ich kann einfach nicht verstehen, wie es funktioniert. Da mein Skript ein Windows-Äquivalent benötigt, habe ich [http://stackoverflow.com/a/3981086/314056] verwendet. Meiner Meinung nach ist das ein viel sauberer und weniger magischer Ansatz. Kann ich etwas ähnliches unter Linux tun? – Christian

+0

@Christian Du könntest so etwas Ähnliches mit BASH machen, '% 1' wird zu' $ 1' (und '$ 2', wenn' $ 1' ein Argument erwartet). In der Tat, viele Leute tun es einfach so, fahren durch die Argumente durch 'shift' und führen das aktuelle Argument durch einen Schalter.'getopt' behandelt nur all diese magischen Argumente, plus das obligatorische Argument, das nach Ihnen sucht, so viele mögen diese Bequemlichkeit. –