2016-02-13 82 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

謝謝你的回答:) –