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

发布于 2024-07-17 01:54:51 字数 548 浏览 4 评论 0原文

我正在编写一个小程序,该程序应该在远程服务器上执行命令(假设有一个围绕 ssh [主机名] [命令] 的相当愚蠢的包装器)。

我想这样执行它:

./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 支持这种语法吗? 如果是这样:怎么办? 如果不是:解决这个问题的最佳方法是什么?

I'm writing a small program that's supposed to execute a command on a remote server (let's say a reasonably dumb wrapper around ssh [hostname] [command]).

I want to execute it as such:

./floep [command] 

However, I need to pass certain command lines from time to time:

./floep -v [command]

so I decided to use optparse.OptionParser for this. Problem is, I sometimes the command also has argument, which works fine if I do:

./floep -v "uname -a"

But I also want it to work when I use:

./floep -v uname -a

The idea is, as soon as I come across the first non-option argument, everything after that should be part of my command.

This, however, gives me:

Usage: floep [options]

floep: error: no such option: -a

Does OptionParser support this syntax? If so: how?
If not: what's the best way to fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

萌酱 2024-07-24 01:54:51

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

Try using 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)

When run:

$ ./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']
苏大泽ㄣ 2024-07-24 01:54:51

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

引用上面的链接:

disable_interspersed_args()

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

OptionParser instances can actually be manipulated during the parsing operation for complex cases. In this case, however, I believe the scenario you describe is supported out-of-the-box (which would be good news if true! how often does that happen??). See this section in the docs: Querying and manipulating your option parser.

To quote the link above:

disable_interspersed_args()

Set parsing to stop on the first non-option. Use this if you have a
command processor which runs another command which has options of its
own and you want to make sure these options don’t get confused. For example,
each command might have a different set of options.

深居我梦 2024-07-24 01:54:51
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
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
靖瑶 2024-07-24 01:54:51

您可以使用如下所示的 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
${@}

${@} 为您提供未被 Shift 调用消耗的命令行的其余部分。
要使用 ssh,您只需将行从
${@}

ssh ${用户}@${主机} ${@}

test.sh echo bla
bla

test.sh -v echo bla
-v
bla

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

You can use a bash script like this:

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

The ${@} gives you the rest of the command line that was not consumed by the shift calls.
To use ssh you simply change the line from
${@}
to
ssh ${user}@${host} ${@}

test.sh echo bla
bla

test.sh -v echo bla
-v
bla

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文