5

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

我想这样执行它:

./floep [命令]

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

./floep -v [命令]

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

./floep -v "uname -a"

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

./floep -v uname -a

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

然而,这给了我:

用法:floep [选项]

浮动:错误:没有这样的选项:-a

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

4

4 回答 4

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
选项:{'verbose': None} 参数:['foo', '-v', 'bar']
$ ./options.py -v foo bar
选项:{'verbose': True} 参数:['foo', 'bar']
$ ./options.py foo -a bar
选项:{'verbose': None} 参数:['foo', '-a', 'bar']
于 2009-04-03T23:33:45.123 回答
1

OptionParser 实例实际上可以在复杂情况的解析操作期间进行操作。但是,在这种情况下,我相信您描述的场景是开箱即用的(如果属实,这将是个好消息!这种情况多久发生一次??)。请参阅文档中的此部分:查询和操作您的选项解析器

引用上面的链接:

disable_interspersed_args()

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

于 2009-04-03T23:29:02.077 回答
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
于 2009-04-03T23:43:06.880 回答
-1

您可以使用这样的 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

于 2009-04-03T23:03:02.280 回答