1

I am trying to filter out first 3 line of /proc/meminfo using pipe and head command.

so basically i need to run this in Python:

cat /proc/meminfo | head -3

I am using below line in my code :

subprocess.call(["cat", "/proc/meminfo", "|", "head", "-3"])

While just using subprocess.call(["cat", "/proc/meminfo"]) I am getting whole list but I am just interested in first 3 line.

Using above command is giving me below error:

cat: invalid option -- '3'
Try `cat --help' for more information.

Any suggestions?

Remi Guan
  • 21,506
  • 17
  • 64
  • 87
  • pipe is provided by the shell, thus you failed. You may try subprocess.call(["/bin/bash", "-c", "/bin/cat /proc/meminfo | /usr/bin/head -3"]) – Ken Cheung Oct 28 '15 at 08:39
  • There's no need to create a subprocess just to read a file. See my solution below. – Tom Karzes Oct 28 '15 at 08:44

5 Answers5

2

/proc/meminfo is just a file. You don't need a subprocess to read it. Simply open and read it as a file. Here is all you need:

fh = open('/proc/meminfo', 'r')
lines = fh.readlines()
fh.close()

first_lines = lines[:3]

The first_lines list will contain the first three lines (including trailing newline characters).

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
  • So...a XY problem again? – Remi Guan Oct 28 '15 at 08:45
  • or even `list(itertools.islice(open('/proc/meminfo'), 3))` -- it doesn't matter in this case but in general, if the file is large then `islice()` is much more efficient then `.readlines()` that reads *all* lines. – jfs Oct 29 '15 at 19:25
1

To use pip you have to enable shell as shell=True, however it's not advisable specifically because of security reason . You can do this alternative,

import subprocess
ps = subprocess.Popen(('cat', '/proc/meminfo'),stdout=subprocess.PIPE)
output = subprocess.check_output(('head', '-3'), stdin=ps.stdout)
print output
nagato
  • 93
  • 5
0

The pipe is a shell syntax element. You need to run the code in a shell to use a pipe:

subprocess.call(["cat /proc/meminfo | head -3"], shell=True)

From the manual:

If shell is True, the specified command will be executed through the shell. This can be useful if you are using Python primarily for the enhanced control flow it offers over most system shells and still want convenient access to other shell features such as shell pipes, filename wildcards, environment variable expansion, and expansion of ~ to a user’s home directory.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
0

Well head actually accepts an argument, so the pipe is not actually necessary. The following should give the expected result.

subprocess.call(["head", "-3", "/proc/meminfo"])
Vijay Kumar
  • 161
  • 4
  • Thanks Vijay... This is what i was looking for without using much a code but one liner to solve my purpose... Working perfectly – user3262968 Oct 28 '15 at 08:54
0

following this document

In default, subprocess.call with shell=False will disables all shell based features including pipe. When using shell=True, pipes.quote() can be used to properly escape whitespace and shell metacharacters in strings that are going to be used to construct shell commands.

you can use this code

subprocess.call("cat /proc/meminfo | head -3", shell=True)
Nks Sai
  • 23
  • 2