简体   繁体   English

相当于Python中的%*

[英]%* equivalent in python

Does anybody know what is the equivalent of batch script's %* in python ? 有人知道python中批处理脚本的%*等效吗?

Clarification: in a batch file %* is all parameters specified in the command line -- this is very useful if you want to forward the parameters to another program. 说明:在批处理文件%*是在命令行中指定的所有参数-如果要将参数转发到另一个程序,这将非常有用。

My Problem is that I want to convert one batch call to a python call : 我的问题是我想将一个批处理调用转换为python调用:

Batch call is : 批量调用是:

trial.bat %*


what is the equivalent python call ?(PS I know I can just go through the whole sys.argv list and append parameters in some string and pass that to the batch file, but I am looking for a simpler solution here) 什么是等效的python调用?(PS,我知道我可以遍历整个sys.argv列表并在一些字符串中附加参数,然后将其传递给批处理文件,但是我在这里寻找一种更简单的解决方案)

I tried following : 我尝试以下:

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

But that is not working. 但这是行不通的。 I tried similar thing using argparse as well. 我也尝试过使用argparse类似的操作。 Its not working either. 它也不起作用。 Please help. 请帮忙。

sys.argv[1:] is pretty close. sys.argv[1:]非常接近。 The thing is that argv is a list of arguments, and [1:] is a slice of a list, which is again a list. 问题是argv是参数列表,而[1:]是列表的一部分,而列表又是列表。 If you want a string with all arguments combined, you can join them again: 如果您想将所有参数组合在一起的字符串,可以再次加入它们:

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

Or even better, you use the subprocess module which method's accept a list of arguments: 甚至更好的是,您使用subprocess模块,该方法的方法接受参数列表:

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

Subprocess is much more flexible when handling parameters and will also behave similar to the parsing in argv . 子进程在处理参数时更加灵活,其行为也类似于argv的解析。 As an example, when calling a script with the arguments foo "hello world" bar , argv will contain this: 例如,当使用参数foo "hello world" bar调用脚本时,argv将包含以下内容:

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

Now if we were to simply join this list, we would get a single string 现在,如果我们只是加入此列表,我们将得到一个字符串

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

As you can see, the information of the compound argument hello world is lost, resulting in a completely different meaning. 如您所见,复合参数hello world的信息丢失了,从而导致了完全不同的含义。

When using subprocess however, you keep your list and subprocess will automatically make sure to pass these arguments correctly to the called program. 但是,在使用subprocess时,您将保留列表,并且子流程将自动确保将这些参数正确传递给被调用的程序。 So the called program will be able to get hello world as a combined argument too. 因此,被调用的程序也可以将hello world作为组合参数。

You want subprocess.Popen (or one of it's convenience wrappers): 您需要subprocess.Popen (或它的便利包装之一):

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

It's definitely preferred to os.system . 绝对首选os.system The advantage here is that commandline arguments which may need to be quoted to keep their meaning effectively stay quoted. 这样做的好处是命令行参数可能需要加引号,以使其含义有效地保持被引号。 Additionally, this alternative is probably safer than os.system since it avoids creating a subshell. 另外,这种选择可能比os.system更安全,因为它避免了创建子shell。

If you want to use os.system , you need to put the command line back together manually. 如果要使用os.system ,则需要手动将命令行重新组合在一起。 Python has already parsed the command line apart into separate arguments (or MSVCRT has done it on Python's behalf). Python已经将命令行解析为单独的参数(或者MSVCRT代表Python进行了解析)。 This means you need to not just concatenate them back together, but also quote them appropriately. 这意味着您不仅需要将它们重新连接在一起,还需要适当地引用它们。

There is nothing in the stdlib that handles the "quote them appropriately" exactly the way MSVCRT wants. stdlib中没有任何东西可以完全按照MSVCRT的要求来“适当地报价”。 That's partly because Windows quoting is actually ambiguous; 部分原因是Windows报价实际上是模棱两可的。 there are some cases where it is impossible to round-trip things. 在某些情况下,不可能往返。 But, for simple cases, either POSIX-style quoting (with shlex.quote ) or just sticking explicit quotes around each argument will work. 但是,在简单的情况下,可以使用POSIX风格的引号(带有shlex.quote )或仅在每个参数周围使用显式引号。 So, either of these: 因此,这些:

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

Then: 然后:

os.system(args)

But using subprocess is better than os.system . 但是使用subprocess os.systemos.system更好。 One reason is that you don't have to fiddle with quoting things; 原因之一是您不必摆弄报价。 you can just do this: 您可以这样做:

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

Someone still needs to put the list of arguments back together in a string so it can be passed to the shell, but now that "someone" is the subprocess module rather than your code. 仍然有人需要将参数列表放回字符串中,以便可以将其传递到外壳程序,但是现在“某人”是subprocess模块,而不是您的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM