4

I'm looking for the best way to use bash commands from within python. What ways are there? I know of os.system and subprocess.Popen.

I have tried these:

bootfile = os.system("ls -l /jffs2/a.bin | cut -d '/' -f 4")
print bootfile

This returns a.bin as expected but also it retuns 0 afterwards and so prints:

a.bin
0

with bootfile now being set to 0. The next time I print bootfile it just shows up as 0. Which is the exit value I guess, how do i stop this value interfering?

I have also tried:

bootfile = subprocess.Popen("ls -l /jffs2/a.bin | cut -d '/' -f 4")
print bootfile

but it seems to break the script, as in I get nothing returned at all, have I done that right?

Also which of these is better and why? Are there other ways and what is the preferred way?

5
  • 2
    What is your goal with your bash commands ? I'm sure you could do this in python without calling bash. Commented Feb 28, 2013 at 13:08
  • 1
    Have you considered reading the documentation for subprocess.Popen at all? Commented Feb 28, 2013 at 13:09
  • I wish to return a symlink, this points to the name of the firmware. So in this case I want to return a.bin which will actually point to the name of the actual bin file Commented Feb 28, 2013 at 13:09
  • I am reading it now, I was using an example online and it seems it was terribly wrong. Commented Feb 28, 2013 at 13:10
  • 4
    @Paul so you want os.readlink('/jffs2/a.bin')? Commented Feb 28, 2013 at 13:10

3 Answers 3

3

Using os.readlink (proposed by @kojiro) and os.path.basename for getting only the namefile:

os.path.basename(os.readlink('/jffs2/a.bin'))
Sign up to request clarification or add additional context in comments.

1 Comment

That's perfect thanks, now I want to know why popen returns none and I am satisfied.
2

kojiro's comment about os.readlink is probably what you want. I am explaining what you were trying to implement.

os.system would return you exit status of the command run.

subprocess.Popen will create a pipe, so that you can capture the output of the command run.
Below line will capture output of the command run:

bootfile = subprocess.Popen(["bash","-c","ls -l /jffs2/a.bin | cut -d '/' -f 4"], stdout=subprocess.PIPE).communicate()[0]

More details at http://docs.python.org/library/subprocess.html

3 Comments

That subprocess.Popen command won't work. See the subprocess.Popen docs (in particular the "shell" parameter to Popen()).
thanks that's great, I jsut have to adjust it because instead of returning a.bin, it returns jffs2/a.bin and then none, setting the variable to none then.
I got it to return the binfile now, however it still returns "none" afterwards. You had changed the cut command for some reason :)
1

The right answer, as @kojiro says, is:

os.readlink('/jffs2/a.bin')

But if you really wanted to do this the complicated way, then in Python 2.7:

cmd = "ls -l /jffs2/a.bin | cut -d '/' -f 4"
bootfile = subprocess.check_output(cmd, shell=True)

Or on older Pythons:

cmd = "ls -l /jffs2/a.bin | cut -d '/' -f 4"
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
bootfile = p.communicate()[0]
if p.returncode != 0:
    raise Exception('It failed')

3 Comments

thanks for that, good to know different ways. My problem with popen is bootfile = p.communicate[0] returns both the correct answer and then None after it.
I just fixed a typo... try p.communicate()[0]. (p.communicate() returns a tuple, the [0] bit takes the first element from that tuple).
Hi, I had fixed your typo myself thanks, I should have mentioned that. The thing is, when I am accessing index 0 it is giving me the correct value and none also, then marking the variable as none. Which makes no sense to me. I did it another way but not knowing why bothers me :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.