2011-09-06 37 views
8

tôi có thể chạy bình thường trên dòng lệnh trong Linux:Python - Cách gọi lệnh bash bằng đường ống?

$ tar c my_dir | md5sum 

Nhưng khi tôi cố gắng gọi nó với Python tôi nhận được một lỗi:

>>> subprocess.Popen(['tar','-c','my_dir','|','md5sum'],shell=True) 
<subprocess.Popen object at 0x26c0550> 
>>> tar: You must specify one of the `-Acdtrux' or `--test-label' options 
Try `tar --help' or `tar --usage' for more information. 
+0

Tại sao các bạn băm một file tar? Bạn muốn tìm kiếm những thay đổi trong nội dung tập tin? hoặc xác minh tệp tar được tạo bên ngoài? – tMC

Trả lời

9

Bạn phải sử dụng subprocess.PIPE, cũng, để tách lệnh, bạn nên sử dụng shlex.split() để ngăn các hành vi lạ trong một số trường hợp:

from subprocess import Popen, PIPE 
from shlex import split 
p1 = Popen(split("tar -c mydir"), stdout=PIPE) 
p2 = Popen(split("md5sum"), stdin=p1.stdout) 

Nhưng để tạo lưu trữ và tạo c hecksum, bạn nên sử dụng các mô-đun tích hợp Python tarfilehashlib thay vì gọi các lệnh shell.

+0

tarfile và hashlib sẽ thích hợp hơn. Nhưng làm thế nào để băm một đối tượng tarfile? – Greg

+1

@Greg không băm đối tượng tarfile, mở tệp kết quả giống như bất kỳ tệp nào khác bằng cách sử dụng 'open()' và sau đó băm nội dung của nó. – MatToufoutu

+0

Làm cho tinh thần. Điều đó làm việc nhưng tôi nhận được một giá trị băm khác với lệnh gốc. Đó có phải là mong đợi không? – Greg

3

Ok, tôi không chắc chắn lý do tại sao nhưng điều này dường như làm việc:

subprocess.call("tar c my_dir | md5sum",shell=True) 

Bất cứ ai biết tại sao mã gốc không hoạt động?

+2

ống | là một nhân vật mà shell hiểu được để kết nối các đầu vào và đầu ra lệnh với nhau. Nó không phải là một lý lẽ mà tar hiểu, cũng không phải là một mệnh lệnh. Bạn đang cố thực hiện mọi thứ như các đối số cho lệnh tar, trừ khi bạn tạo một subshell. – tMC

+1

Các tác phẩm vì toàn bộ lệnh được chuyển tới * shell * và * shell * hiểu '|'. Popen gọi quá trình này và chuyển trực tiếp vào các đối số. Đối với Popen, điều này được kiểm soát với 'shell =' và truyền một chuỗi (không phải là một danh sách), IIRC. –

1
>>> from subprocess import Popen,PIPE 
>>> import hashlib 
>>> proc = Popen(['tar','-c','/etc/hosts'], stdout=PIPE) 
>>> stdout, stderr = proc.communicate() 
>>> hashlib.md5(stdout).hexdigest() 
'a13061c76e2c9366282412f455460889' 
>>> 
2

gì bạn thực sự muốn là để chạy một tiến trình con vỏ bằng lệnh shell như một tham số:

>>> subprocess.Popen(['sh', '-c', 'echo hi | md5sum'], stdout=subprocess.PIPE).communicate() 
('764efa883dda1e11db47671c4a3bbd9e -\n', None) 
Các vấn đề liên quan