3

Im trying to get the number of lines in the output of ls -l | awk '{print $1}', which is 7 as shown below.

total
drwxrwxr-x
drwxrwxr-x
-rw-rw-r--
-rw-rw-r--
-rw-rw-r--
-rw-r--r--

I tried to store this value in the variable count but when I print count, the value is 0 instead of 7. I don't know why.

import subprocess

count = subprocess.call('ls -l | awk '{print $1}' | wc -l', shell=True)
print count

OUTPUT:

7
0
Abhay Nayak
  • 1,069
  • 1
  • 11
  • 25
  • Why not using `os.listdir`? – Adonis Apr 12 '18 at 07:40
  • 4
    Possible duplicate of [Get a return value using subprocess](https://stackoverflow.com/questions/9041141/get-a-return-value-using-subprocess) – FlyingTeller Apr 12 '18 at 07:42
  • 1
    `subprocess.call()` does not return the stdout of the process called, but the returncode. In this case this is `0` (no error occured) – FlyingTeller Apr 12 '18 at 07:43
  • 1
    is there anyway to store the actual answer instead of the return value? because Im using pipes and using subprocess.calls() is easier that way – Abhay Nayak Apr 12 '18 at 07:47
  • You don't want the return code here (it's 0 because the shell command exited without an error); rather, you want the standard output of the subprocess. [`subprocess.check_output`](https://docs.python.org/3/library/subprocess.html#subprocess.check_output) should do what you want. – wildwilhelm Apr 12 '18 at 07:52
  • 1
    @Adonis Im trying to learn how to count lines from the shell, not necessarily only the directories, hence `subprocess.call()` – Abhay Nayak Apr 12 '18 at 07:53
  • 1
    @wildwilhelm is there a way to use pipes with `subprocess.check_output` ? – Abhay Nayak Apr 12 '18 at 07:55
  • The function signature for check_output is the same as for run or call or the others. You can do shell=True, and you can redirect stderr to stdout. Anything more complicated than that, and you can look to explicitly construct a Popen instance, as @toheedNiaz has suggested. – wildwilhelm Apr 12 '18 at 07:58
  • 1
    Thanks for the help @wildwilhelm . I tried toheedNiaz's answer, it gives ['7\n'] which is great but Mufeed's answer makes string manipulation easier for me, give 7 directly. Thanks all :) – Abhay Nayak Apr 12 '18 at 08:09

2 Answers2

3

You can use subprocess.check_ouput as well. It was specifically meant for checking output as the name suggests.

count = subprocess.check_output("ls -l | awk '{print $1}' | wc -l", shell=True)
Mufeed
  • 3,018
  • 4
  • 20
  • 29
1

Subprocess.call does not return stdout so you need to use Popen instead. Here is what you can do .

import subprocess

count = subprocess.Popen("ls -l | awk '{print $1}' | wc -l",stdout = subprocess.PIPE, shell=True)
print(count.stdout.readlines())
toheedNiaz
  • 1,435
  • 1
  • 10
  • 14