2016-02-13 80 views
2

我想用电话子呼叫子“ls -l命令文件夹|厕所-l”在Python不能做

ls -l folder | wc -l 

我在Python文件中的代码是在这里运行此命令:

subprocess.call(["ls","-l","folder","|","wc","-l"]) 

我得到了这样的错误消息:

ls: cannot access |: No such file or directory 
ls: cannot access wc: No such file or directory 

这就像命令|wc不能调用子读取。

我该如何解决?

+0

管是壳的东西。 shell会分叉两个子进程,并且将第一个子进程的stdout转换为第二个子进程的stdin。你需要自己实现这个逻辑。 – sturcotte06

回答

2

试试用一个字符串作为第一个参数shell选项:

subprocess.call("ls -l folder | wc -l",shell=True) 

虽然这项工作,注意使用shell=True不推荐,因为它可以通过shell injection带来安全性问题。

+0

谢谢你的工作:) :) –

+0

它没有返回预期的结果,它只是这个错误已经消失 – AlokThakur

+0

谢谢AlokThakur。第一个参数必须是一个字符串。应该现在工作。 –

0

您需要自己实施管道逻辑以使其正常工作。

def piped_call(prog1, prog2): 
    out, err = subprocess.call(prog1).communicate() 
    if err: 
    print(err) 
    return None 
    else: 
    return subprocess.call(prog2).communicate(out) 
+0

谢谢你的回答:) –

0

你可以尝试使用subprocess.PIPE,假设你想避免使用subprocess.call(..., shell=True)

import subprocess 

# Run 'ls', sending output to a PIPE (shell equiv.: ls -l | ...) 
ls = subprocess.Popen('ls -l folder'.split(), 
         stdout=subprocess.PIPE) 

# Read output from 'ls' as input to 'wc' (shell equiv.: ... | wc -l) 
wc = subprocess.Popen('wc -l'.split(), 
         stdin=ls.stdout, 
         stdout=subprocess.PIPE) 

# Trap stdout and stderr from 'wc' 
out, err = wc.communicate() 

if err: 
    print(err.strip()) 

if out: 
    print(out.strip()) 

对于Python 3记住这里使用会返回一个byte对象,而不是一个字符串communicate()方法。 :

在这种情况下,你需要将输出转换为使用decode()字符串:

if err: 
    print(err.strip().decode()) 
if out: 
    print(out.strip().decode()) 
+0

谢谢,还在学习子过程:) –

1

您可以设置通过连接一个命令管道一个过程的stdout与另一个人的stdin。在你的例子中,错误和最终输出写入屏幕,所以我没有尝试重定向它们。这通常比communicate更可取,因为它们不是在开始另一个程序之前等待一个程序完成(并鼓励将数据移入父级),它们并行运行。

import subprocess 

p1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE) 
p2 = subprocess.Popen(["wc","-l"], stdin=p1.stdout) 
# close pipe in parent, its still open in children 
p1.stdout.close() 
p2.wait() 
p1.wait() 
+0

谢谢你的回答:) –