在python而不是shell中使用命令行参数

时间:2012-10-02 01:44:15

标签: python command-line-arguments

假设python脚本可以用:

调用
python myscript.py ./mycommand > myoutput.txt

如何确保myscript.py在命令行参数列表中获得./mycommand > myoutput.txt而不是将python myscript.py ./mycommand的输出汇总到文件中?

修改

使用引号会带来其他问题。考虑:

import subprocess
import sys

argList = sys.argv[1].split()

subprocess.call(argList)

然后由:

调用
python myscript.py 'ls -l > ls.out'

结果

ls: cannot access >: No such file or directory
ls: cannot access ls.out: No such file or directory

动机是只有我尝试运行的命令的输出应该保存在文件中。从myscript.pystdout的任何其他输出都不应该转到该文件。看来管道需要使用stdout选项设置为subprocess.call()。有没有办法直接使用参数列表,所以我不必为>2>2&><之类的东西解析它?

2 个答案:

答案 0 :(得分:3)

如果你愿意接受依赖,可以使用Kenneth Reitz's envoy(如果你想从命令行向你的脚本传递任意命令,你仍然需要使用引号。)

from envoy import run
from sys import argv

run(argv[1])

然后你可以使用:

调用它
$ python myscript.py './mycommand > myoutput.txt'

或者,如果您希望在Python文件中使用类似shell的语法,则可以使用sh(以前称为pbs)或plumbum

from sh import ls

with open("myoutput.txt", "w") as outfile:
    ls("-l", _out=outfile)

# Or, in plumbum
from plumbum.cmd import ls

# Yes, this looks crazy, but the docs say it works.
ls["-l"] > "myoutput.txt"

答案 1 :(得分:2)

标准的bash或tcsh shell将解析您自己给出的命令,并将某些特殊字符解释为shell进程本身的方向(示例中的“&gt;”字符)。被叫程序无法控制这个;命令行解析在调用程序之前发生。

在您的示例中,您可以说:

python myscript.py ./mycommand ">" myoutput.txt

引用“&gt;”会告诉shell不要使用它的特殊行为。

子进程模块有两种操作模式;一个带有shell(通常是/ bin / sh)的中间过程 - 这是你给Popen对象一个shell=True关键字参数的时候。当您以这种方式调用它时,它会调用shell来解析参数文本,然后shell会调用您指定的命令作为从程序中删除的子进程。

另一种操作模式是默认值shell=False。这将创建一个子进程并直接填充其ARGV数组,而不会尝试解释命令中的字符。

最终结果是,如果要从解释特殊字符的shell发出命令并包含特殊字符,则必须将它们转义或引用它们。如果您从subprocess标准库模块调用子进程,则可以将任意文本作为要处理的子进程的ARGV的元素传递,而不用担心它们会被中介以某种特殊方式解释shell进程。