python中的%*等价物

时间:2013-11-27 19:31:04

标签: python batch-file argparse argv

有人知道python中批处理脚本%*的等价物吗?

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

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

批量电话是:

trial.bat %*

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

我试过以下:

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

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

3 个答案:

答案 0 :(得分:4)

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作为一个组合参数。

答案 1 :(得分:3)

您想要subprocess.Popen(或其中一个便利包装器):

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

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

答案 2 :(得分:0)

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

stdlib中没有任何内容可以按照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模块而不是代码。