【问题标题】:%* equivalent in python%* 在 python 中的等价物
【发布时间】:2013-12-13 14:58:00
【问题描述】:

有人知道python中批处理脚本的%*是什么吗?

澄清:在批处理文件中%* 是在命令行中指定的所有参数——如果你想将参数转发到另一个程序,这非常有用。

我的问题是我想将一个批处理调用转换为 python 调用:

批量调用是:

trial.bat %*


什么是等效的 python 调用?(PS 我知道我可以遍历整个 sys.argv 列表并在一些字符串中附加参数并将其传递给批处理文件,但我正在寻找一个更简单的解决方案在这里)

我尝试了以下操作:

os.system('trial.bat '+sys.argv)
os.system('trial.bat '+sys.argv[1:])

但这不起作用。我也使用argparse 尝试过类似的事情。它也不起作用。请帮忙。

【问题讨论】:

    标签: python batch-file argparse argv


    【解决方案1】:

    sys.argv[1:] 非常接近。问题是argv 是一个参数列表,[1:] 是一个列表的一部分,它又是一个列表。如果你想要一个包含所有参数的字符串,你可以再次加入它们:

    os.system('trial.bat ' + ' '.join(sys.argv[1:]))
    

    或者更好的是,您使用subprocess 模块,哪个方法接受参数列表:

    subprocess.check_call(['trial.bat'] + sys.argv[1:])
    

    子进程在处理参数时更加灵活,并且其行为也类似于argv 中的解析。例如,当使用参数foo "hello world" bar 调用脚本时,argv 将包含以下内容:

    >>> sys.argv[1:]
    ['foo', 'hello world', 'bar']
    

    现在如果我们只是加入这个列表,我们会得到一个字符串

    >>> ' '.join(sys.argv[1:])
    'foo hello world bar'
    

    如您所见,复合参数hello world的信息丢失了,导致完全不同的含义。

    然而,当使用subprocess 时,你保留你的列表并且子进程会自动确保将这些参数正确地传递给被调用的程序。所以被调用的程序也可以得到hello world作为组合参数。

    【讨论】:

    • awesome..os.system('trial.bat ' + ' '.join(sys.argv[1:])) 为我工作..谢谢。
    • 你需要一个shell来运行一个批处理文件,所以subprocess.check_call将不起作用。
    • @abarnert 不,批处理文件可以由系统执行,它们不需要通过 shell 运行。它绝对有效。
    • @poke:the CreateProcess documentation 不是这么说的。
    • @abarnert 但实践证明并非如此。就像你可以双击一个bat文件一样,你可以在没有shell的情况下执行它。
    【解决方案2】:

    你想要subprocess.Popen(或它的便利包装之一):

    import subprocess
    import sys
    process = subprocess.Popen(['trial.bat'] + sys.argv[1:])
    process.wait()
    

    绝对首选os.system。这里的优点是可能需要引用以保持其含义有效的命令行参数。此外,这种替代方案可能比os.system 更安全,因为它避免了创建子shell。

    【讨论】:

    • 除非你不能在没有shell的情况下运行.bat文件。
    • 另外,为什么要创建一个Popen 只是为了调用wait 而不是仅仅执行call
    • “除非你不能在没有 shell 的情况下运行 .bat 文件。”你能出示相关的文档吗?
    • @abarnert -- 我不知道没有 shell 的 .bat -- 我已经很长时间没有使用 Windows 了……其他人似乎认为它可以工作。至于使用 Popen 然后只是等待它,我想指向Popen,因为它是底层接口。所有其他便利功能只是它的包装器(正如我在回答中提到的那样)。当然,你可以在这里使用call。我的主要观点是“不要使用os.system——subprocess 更好”...
    • @nephi12: subprocess.Popen 在 Windows 上调用 CreateProcesslpApplicationName 参数的 CreateProcess 文档说“此模块可以是基于 Windows 的应用程序。如果适当的子系统在本地计算机...要运行批处理文件,您必须启动命令解释器;将 lpApplicationName 设置为 cmd.exe 并将 lpCommandLine 设置为以下参数:/c 加上批处理文件的名称。"
    【解决方案3】:

    如果要使用os.system,则需要手动将命令行重新组合在一起。 Python 已经将命令行解析为单独的参数(或 MSVCRT 已代表 Python 完成)。这意味着您不仅需要将它们重新连接在一起,还需要适当地引用它们。

    标准库中没有任何内容可以完全按照 MSVCRT 的方式处理“适当地引用它们”。这部分是因为 Windows 引用实际上是模棱两可的。在某些情况下,不可能往返。但是,对于简单的情况,POSIX 风格的引用(使用shlex.quote)或者只是在每个参数周围加上明确的引号都可以。所以,其中任何一个:

    args = ' '.join(shlex.quote(arg) for arg in [program] + sys.argv[1:])
    args = ' '.join('"{}"'.format(arg) for arg in [program] + sys.argv[1:])
    

    然后:

    os.system(args)
    

    但是使用subprocess 比使用os.system 更好。一个原因是您不必摆弄引用的东西。你可以这样做:

    subprocess.check_call([program] + sys.argv[1:], shell=True)
    

    仍然需要有人将参数列表重新组合成一个字符串,以便将其传递给 shell,但现在“某人”是 subprocess 模块,而不是您的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-06
      • 2013-02-06
      • 2012-03-22
      • 2016-12-27
      • 2021-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多