2009-04-03 1 views
5

Sto scrivendo un piccolo programma che dovrebbe eseguire un comando su un server remoto (diciamo un wrapper abbastanza stupido attorno a ssh [hostname] [command]).OptionParser - supportare qualsiasi opzione alla fine della riga di comando

voglio eseguirlo come tale:

./floep [command]

Tuttavia, ho bisogno di passare alcune righe di comando di volta in volta:

./floep -v [command]

così ho deciso di utilizzare per questo optparse.OptionParser . Il problema è, a volte il comando è anche l'argomento, che funziona bene se lo faccio:

./floep -v "uname -a"

Ma voglio anche farlo funzionare quando uso:

./floep -v uname -a

L'idea è, non appena Mi imbatto nel primo argomento non opzionale, ogni cosa dopo dovrebbe essere parte del mio comando.

Questo, tuttavia, mi dà:

Usage: floep [options] 

floep: error: no such option: -a

Does OptionParser supportare questa sintassi? Se é cosi, come? In caso contrario: qual è il modo migliore per risolvere il problema?

risposta

13

Provare a utilizzare disable_interspersed_args()

#!/usr/bin/env python 
from optparse import OptionParser 

parser = OptionParser() 
parser.disable_interspersed_args() 
parser.add_option("-v", action="store_true", dest="verbose") 
(options, args) = parser.parse_args() 

print "Options: %s args: %s" % (options, args) 

Quando viene eseguito:

 
$ ./options.py foo -v bar 
Options: {'verbose': None} args: ['foo', '-v', 'bar'] 
$ ./options.py -v foo bar 
Options: {'verbose': True} args: ['foo', 'bar'] 
$ ./options.py foo -a bar 
Options: {'verbose': None} args: ['foo', '-a', 'bar'] 
+0

Grazie! .. Questa è una risposta molto approfondita e ha funzionato perfettamente – Evert

-2

È possibile utilizzare uno script bash come questo:

#!/bin/bash 
while [ "-" == "${1:0:1}" ] ; do 
    if [ "-v" == "${1}" ] ; then 
    # do something 
    echo "-v" 
    elif [ "-s" == "${1}" ] ; then 
    # do something 
    echo "-s" 
    fi 
    shift 
done 
${@} 

I $ {@} ti dà il resto della riga di comando che non è stata consumata dalle chiamate di turno. Per usare SSH è sufficiente modificare la riga da $ {} @ a ssh $ {user} @ $ {host} $ {} @

test.sh eco bla bla

test. sh -v echo bla
-v
bla

test.sh -v -s eco bla
-v
-s
bla

+0

Anche se la risposta potrebbe essere corretta, per me questo è un esercizio di pitone – Evert

1

Le istanze OptionParser possono essere effettivamente manipolate durante l'operazione di analisi per casi complessi. In questo caso, tuttavia, credo che lo scenario che descrivi sia supportato immediatamente (che sarebbe una buona notizia se fosse vero! Quanto spesso accade?). Vedi questa sezione nei documenti: Querying and manipulating your option parser.

Per citare il link qui sopra:

disable_interspersed_args()

Set analisi per fermare il primo non-opzione. Utilizzare questo se si dispone di un processore di comandi che esegue un altro comando che dispone di opzioni del proprio e si desidera assicurarsi che queste opzioni non vengano confuse. Ad esempio, ogni comando potrebbe avere un diverso set di opzioni.

1
from optparse import OptionParser 
import subprocess 
import os 
import sys 

parser = OptionParser() 
parser.add_option("-q", "--quiet", 
        action="store_true", dest="quiet", default=False, 
        help="don't print output") 
parser.add_option("-s", "--signal", 
        action="store_true", dest="signal", default=False, 
        help="signal end of program and return code") 

parser.disable_interspersed_args() 
(options, command) = parser.parse_args() 

if not command: 
    parser.print_help() 
    sys.exit(1) 

if options.quiet: 
    ret = subprocess.call(command, stdout=open(os.devnull, 'w'), 
          stderr=subprocess.STDOUT) 
else: 
    ret = subprocess.call(command) 

if options.signal: 
    print "END OF PROGRAM!!! Code: %d" % ret