Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - How to call bash commands with pipe?

I can run this normally on the command line in Linux:

$ tar c my_dir | md5sum

But when I try to call it with Python I get an error:

>>> 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.
like image 847
Greg Avatar asked Sep 06 '11 17:09

Greg


People also ask

How do I use pipes in bash?

In bash, a pipe is the | character with or without the & character. With the power of both characters combined we have the control operators for pipelines, | and |&. As you could imagine, stringing commands together in bash using file I/O is no pipe dream. It is quite easy if you know your pipes.

How do you use the pipe command in Python?

pipe() method in Python is used to create a pipe. A pipe is a method to pass information from one process to another process.

Can you run bash commands in Python?

Is there any way to execute the bash commands and scripts in Python? Yeah, Python has a built-in module called subprocess which is used to execute the commands and scripts inside Python scripts.

Can you use pipe in shell script?

Pipe may be the most useful tool in your shell scripting toolbox. It is one of the most used, but also, one of the most misunderstood. As a result, it is often overused or misused. This should help you use a pipe correctly and hopefully make your shell scripts much faster and more efficient.


3 Answers

You have to use subprocess.PIPE, also, to split the command, you should use shlex.split() to prevent strange behaviours in some cases:

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

But to make an archive and generate its checksum, you should use Python built-in modules tarfile and hashlib instead of calling shell commands.

like image 102
mdeous Avatar answered Sep 24 '22 03:09

mdeous


Ok, I'm not sure why but this seems to work:

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

Anyone know why the original code doesn't work?

like image 29
Greg Avatar answered Sep 23 '22 03:09

Greg


What you actually want is to run a shell subprocess with the shell command as a parameter:

>>> subprocess.Popen(['sh', '-c', 'echo hi | md5sum'], stdout=subprocess.PIPE).communicate()
('764efa883dda1e11db47671c4a3bbd9e  -\n', None)
like image 33
Dag Avatar answered Sep 24 '22 03:09

Dag