假设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.py
到stdout
的任何其他输出都不应该转到该文件。看来管道需要使用stdout
选项设置为subprocess.call()
。有没有办法直接使用参数列表,所以我不必为>
,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进程。