Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将子流程标准输出管道化为变量_Python_Subprocess_Pipe_Python 2.6 - Fatal编程技术网

Python 将子流程标准输出管道化为变量

Python 将子流程标准输出管道化为变量,python,subprocess,pipe,python-2.6,Python,Subprocess,Pipe,Python 2.6,我想使用subprocess模块在pythong中运行一个命令,并将输出存储在一个变量中。但是,我不希望将命令的输出打印到终端。 对于此代码: def storels(): a = subprocess.Popen("ls",shell=True) storels() 我在终端中获取目录列表,而不是将其存储在a中。我也试过: def storels(): subprocess.Popen("ls > tmp",shell=True) a = open(

我想使用subprocess模块在
pythong
中运行一个命令,并将输出存储在一个变量中。但是,我不希望将命令的输出打印到终端。 对于此代码:

def storels():
   a = subprocess.Popen("ls",shell=True)
storels()
我在终端中获取目录列表,而不是将其存储在
a
中。我也试过:

 def storels():
       subprocess.Popen("ls > tmp",shell=True)
       a = open("./tmp")
       [Rest of Code]
 storels()
这也会将ls的输出打印到我的终端。我甚至用有点过时的os.system方法尝试过这个命令,因为在终端中运行
ls>tmp
根本不会将
ls
打印到终端,而是将其存储在
tmp
中。然而,同样的事情也发生了

编辑:

在遵循marcog的建议后,我得到了以下错误,但仅在运行更复杂的命令时<代码>cdrecord--帮助。Python给出了以下结论:

Traceback (most recent call last):
  File "./install.py", line 52, in <module>
    burntrack2("hi")
  File "./install.py", line 46, in burntrack2
    a = subprocess.Popen("cdrecord --help",stdout = subprocess.PIPE)
  File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
    errread, errwrite)
  File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory
回溯(最近一次呼叫最后一次):
文件“/install.py”,第52行,在
burntrack2(“hi”)
文件“/install.py”,第46行,在burntrack2中
a=subprocess.Popen(“cdrecord--help”,stdout=subprocess.PIPE)
文件“/usr/lib/python2.6/subprocess.py”,第633行,在__
错误读取,错误写入)
文件“/usr/lib/python2.6/subprocess.py”,第1139行,在执行子进程中
引发子对象异常
OSError:[Errno 2]没有这样的文件或目录

要获取
ls
的输出,请使用

命令
cdrecord--help
将输出到stderr,因此您需要将该indstead管道化。您还应该像我在下面所做的那样,将命令分解为一个令牌列表,或者另一种方法是传递
shell=True
参数,但是如果您不控制命令字符串的内容,这将触发一个完全打开的shell,这可能是危险的

>>> proc = subprocess.Popen(['cdrecord', '--help'], stderr=subprocess.PIPE)
>>> output = proc.stderr.read()
>>> print output
Usage: wodim [options] track1...trackn
Options:
    -version    print version information and exit
    dev=target  SCSI target to use as CD/DVD-Recorder
    gracetime=# set the grace time before starting to write to #.
...
如果您有一个同时输出到stdout和stderr的命令,并且希望合并它们,那么可以通过将stderr管道化到stdout,然后捕获stdout来实现

subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
如所述,您应该使用
proc.communicate()
而不是
proc.read()


使用
a=subprocess.Popen(“cdrecord--help”,stdout=subprocess.PIPE)
,您需要使用列表或使用
shell=True

这两种方法都可以。前者更好

a = subprocess.Popen(['cdrecord', '--help'], stdout=subprocess.PIPE)

a = subprocess.Popen('cdrecord --help', shell=True, stdout=subprocess.PIPE)
此外,不应使用
Popen.stdout.read
/
Popen.stderr.read
,而应使用
.communicate()
(有关原因,请参阅子流程文档)


如果您使用的是Python2.7或更高版本,最简单的方法是使用命令。以下是一个例子:

output = subprocess.check_output('ls')
要重定向stderr,还可以使用以下命令:

output = subprocess.check_output('ls', stderr=subprocess.STDOUT)


如果要向命令传递参数,可以使用列表或调用shell并使用单个字符串

output = subprocess.check_output(['ls', '-a'])
output = subprocess.check_output('ls -a', shell=True)

好的,这对“ls”有效,但后来我在尝试运行不同的命令时遇到了不同的问题。当我尝试用这个方法运行“cdrecord--help”时,我得到了一个回溯错误。非常感谢!!成功了。如果你不介意我问的话,你会如何区分使用stdout方法和这个stderr方法?@在这种情况下,我知道用法通常会被转储到stderr。但一般来说,一个简单的测试是
cmd>/dev/null
,如果您仍然看到输出,它将进入stderr。通过管道stderr
cmd 2>/dev/null
确认,它应该消失在
/dev/null
@Insomaniacal中:通常会使用
stdout
,但有时会使用
stderr
;通常,使用
stdout
,除非它不起作用,然后尝试
stderr
。我相信它可以在一些终端中以不同的颜色排列stderr,这样你就可以明显地分辨出来。在Python3下,
输出将不是字符串,而是字节序列。尝试使用
output.decode(encoding='utf-8')
output.decode(encoding='latin-1')
获取字符串。Python文档中不建议只使用
shell=true
作为注释。这不会根据请求抑制输出(“我不希望将命令的输出打印到终端”)。这会为我抑制到终端的所有输出(只要我使用stderr=subprocess.STDOUT来捕获STDOUT和stderr)。您是否有一个示例命令不起作用?Emre,我在Python2.6中看到过这种行为
output = subprocess.check_output('ls')
output = subprocess.check_output('ls', stderr=subprocess.STDOUT)
output = subprocess.check_output(['ls', '-a'])
output = subprocess.check_output('ls -a', shell=True)