OptionParser - 支持命令行末尾的任何选项

时间:2009-04-03 22:52:46

标签: python optparse

我正在编写一个小程序,该程序应该在远程服务器上执行命令(假设ssh [hostname] [command]周围有一个合理的愚蠢包装)。

我想这样执行:

./floep [command] 

但是,我需要不时传递某些命令行:

./floep -v [command]

所以我决定使用optparse.OptionParser。问题是,我有时候命令也有参数,如果我这样做的话可以正常工作:

./floep -v "uname -a"

但我也希望它能在我使用时起作用:

./floep -v uname -a

我的想法是,只要我遇到第一个非选项参数,那之后的所有内容都应该成为我命令的一部分。

然而,这给了我:

Usage: floep [options]

floep: error: no such option: -a

OptionParser是否支持此语法?如果是这样:怎么样? 如果不是:解决这个问题的最佳方法是什么?

4 个答案:

答案 0 :(得分:13)

尝试使用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)

运行时:

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

答案 1 :(得分:1)

对于复杂的情况,在解析操作期间实际上可以操作OptionParser实例。但是,在这种情况下,我相信您所描述的场景是开箱即用的(如果这是真的,那将是个好消息!这种情况经常发生的情况??)。请参阅文档中的此部分:Querying and manipulating your option parser

引用上面的链接:

  

disable_interspersed_args()

     

将解析设置为在第一个非选项上停止。如果您有,请使用此选项   命令处理器,它运行另一个具有其选项的命令   拥有,你想确保这些选项不会混淆。例如,   每个命令可能有一组不同的选项。

答案 2 :(得分: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

答案 3 :(得分:-2)

您可以使用这样的bash脚本:

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

$ {@}为您提供切换调用未使用的其余命令行。 要使用ssh,只需更改行即可     $ {@} 至     ssh $ {user} @ $ {host} $ {@}

test.sh echo bla
bla

test.sh -v echo bla
-v
bla

test.sh -v -s echo bla
-v
-s
bla