cashman04
cashman04

Reputation: 1173

Python TypeError: iteration over non-sequence on simple list

import os

test = os.system("ls /etc/init.d/ | grep jboss- | grep -vw jboss-")
for row in test:
    print row

For some reason this gives the TypeError: iteration over non-sequence error on this.

When I do a print test without the for loop, it gives a list of the jboss instances, plus a "0" at the bottom.. The heck?

Upvotes: 0

Views: 1000

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1123480

os.system() returns the exit code of the process, not the result of the grep commands. This is always an integer. In the meantime, the output of the process itself is not redirected, so it writes to stdout directly (bypassing Python).

You cannot iterate over over an integer.

You should use the subprocess.check_output() function instead if you wanted to retrieve the stdout output of the command.

In this case, you'd be better off using os.listdir() and code the whole search in Python instead:

for filename in os.listdir('/etc/init.d/'):
    if 'jboss-' in filename and not filename.startswith('jboss-'):
        print filename

I've interpreted the grep -vw jboss- command as filtering out filenames that start with jboss; adjust as needed.

Upvotes: 6

miku
miku

Reputation: 188124

The problem is, that os.system returns the exit code. If you want to capture the output, you can use subprocess.Popen:

import subprocess
p = subprocess.Popen("ls", stdout=subprocess.PIPE),
out, err = p.communicate()
files = out.split('\n')

Also note that the use of the subprocess module is encouraged:

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this [os.system] function.

If you do not have to resort to the shell, a pure python solution, as @Martijn Pieters suggests, seems preferable.

Upvotes: 1

Related Questions