我需要这样做:
paste file1 file2 file3 > result
我的python脚本中有以下内容:
from subprocess import call
// other code here.
// Here is how I call the shell command
call ["paste", "file1", "file2", "file3", ">", "result"])
不幸的是我收到了这个错误:
paste: >: No such file or directory.
任何帮助都会很棒!
答案 0 :(得分:5)
如果你明智地决定不使用shell,你需要自己实现重定向。
https://docs.python.org/2/library/subprocess.html处的文档警告您不要使用烟斗 - 但是,您不需要:
import subprocess
with open('result', 'w') as out:
subprocess.call(["paste", "file1", "file2", "file3"], stdout=out)
应该没问题。
答案 1 :(得分:4)
有两种方法。
使用shell=True
:
call("paste file1 file2 file3 >result", shell=True)
重定向>
是一个shell功能。因此,您只能在使用shell时访问它:shell=True
。
保留shell=False
并使用python执行重定向:
with open('results', 'w') as f:
subprocess.call(["paste", "file1", "file2", "file3"], stdout=f)
第二种通常是首选,因为它避免了壳的变幻莫测。
当不使用shell时,>
只是命令行中的另一个字符。因此,请考虑错误消息:
paste: >: No such file or directory.
这表示paste
已收到>
作为参数,并尝试按该名称打开文件。没有这样的文件。因此消息。
作为shell命令行,可以使用该名称创建文件:
touch '>'
如果此类文件已存在,paste
,subprocess
使用shell=False
调用时,会使用该文件进行输入。
答案 2 :(得分:0)
如果您不介意在代码库中添加其他依赖项,则可以考虑安装sh Python模块(当然,使用pip
来自PyPI:sh)。< / p>
这是Python subprocess
模块功能的一个相当聪明的包装器。使用sh
代码看起来像:
#!/usr/bin/python
from sh import paste
paste('file1', 'file2', 'file3', _out='result')
...虽然我认为你想要一些异常处理,所以你可以使用类似的东西:
#!/usr/bin/python
from __future__ import print_function
import sys
from sh import paste
from tempfile import TemporaryFile
with tempfile.TemporaryFile() as err:
try:
paste('file1', 'file2', 'file3', _out='result', _err=err)
except (EnvironmentError, sh.ErrorReturnCode) as e:
err.seek(0)
print("Caught Error: %s" % err.read(), file=sys.stderr)
sh
使这些事情变得非常简单,尽管有一些技巧可以让你更加高级。您还必须注意_out=
与该表单的其他关键字参数之间的差异,而对于大多数其他关键字参数,则需要注意sh
的魔力。
所有sh
魔法让所有读过你代码的人都感到困惑。您可能还会发现使用带有sh
代码的Python模块进行隔行扫描会让您对可移植性问题感到自满。 Python代码通常相当便携,而Unix命令行实用程序可能因操作系统而异,甚至从一个Linux发行版或版本到另一个。有许多shell实用程序以这种透明的方式与Python代码交错,可能会使问题变得不那么明显。