2009-04-03 9 views
5

Estoy escribiendo un pequeño programa que se supone que ejecuta un comando en un servidor remoto (digamos un contenedor razonablemente tonto alrededor de ssh [hostname] [command]).OptionParser - compatible con cualquier opción al final de la línea de comando

quiero ejecutarlo como tal:

./floep [command]

Sin embargo, tengo que pasar ciertas líneas de comando de vez en cuando:

./floep -v [command]

así que decidió usar para este optparse.OptionParser . El problema es que a veces el comando también tiene argumento, que funciona bien si lo hago:

./floep -v "uname -a"

Pero también quiero que funcione cuando uso:

./floep -v uname -a

La idea es, en cuanto Me encuentro con el primer argumento sin opción, todo después de eso debe ser parte de mi comando.

Esto, sin embargo, me da:

Usage: floep [options] 

floep: error: no such option: -a

¿El OptionParser apoyar esta sintaxis? ¿Si es así, cómo? Si no: ¿cuál es la mejor manera de arreglar esto?

Respuesta

13

Intente utilizar 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) 

Cuando se ejecuta:

 
$ ./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

gracias, .. Esa es una respuesta muy completa y funcionó perfectamente – Evert

-2

Se puede utilizar un script bash como esto:

#!/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 
${@} 

Los $ {@} le da el resto de la línea de comandos que no fue consumido por las llamadas de turno. usar ssh basta con cambiar la línea de $ {@} a ssh $ {usuario} @ $ {host} $ {@}

test.sh eco bla bla
prueba

. sh -v eco bla
-v
bla

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

bla

+0

pesar de que su respuesta podría ser correcta, para mí esto es un ejercicio de pitón – Evert

1

casos OptionParser en realidad pueden ser manipuladas durante la operación de análisis sintáctico para casos complejos. En este caso, sin embargo, creo que el escenario que describes es compatible desde el primer momento (lo que sería una buena noticia si es cierto, ¿con qué frecuencia sucede eso?). Consulte esta sección en los documentos: Querying and manipulating your option parser.

citar el enlace anterior:

disable_interspersed_args()

Conjunto de análisis para parar en la primera no sea una opción. Utilice esta opción si tiene un procesador comando que se ejecuta otro comando que tiene opciones de su propio y usted quiere asegurarse de que estas opciones no se confundan. Por ejemplo, cada comando puede tener un conjunto diferente de opciones.

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 
Cuestiones relacionadas