Why won't my python subprocess code work? [duplicate]
Asked Answered
B

2

0
from subprocess import *

test = subprocess.Popen('ls')
print test

When i try to run this simple code, I get an error window saying:

WindowsError: [Error 2] The system cannot find the file specified

I have no clue why I can't get this simple code to work and it's frustrating, any help would be greatly appreciated!

Backdrop answered 14/5, 2013 at 13:20 Comment(4)
do you have "ls.exe" in your path? wait, what OS you're using?Neptunium
Yeah, so how do I make the Windows system know about the ls command?Backdrop
@user2371187 If you want a list of files, it's simpler to use os.listdir().Infallibilism
windows doesn't have ls (unless powershell/mingw32); it uses dirKeeter
C
3

It looks like you want to store the output from a subprocess.Popen() call.
For more information see Subprocess - Popen.communicate(input=None).

>>> import subprocess
>>> test = subprocess.Popen('ls', stdout=subprocess.PIPE)
>>> out, err = test.communicate()
>>> print out
fizzbuzz.py
foo.py
[..]

However Windows shell (cmd.exe) doesn't have a ls command, but there's two other alternatives:

Use os.listdir() - This should be the preffered method since it's much easier to work with:

>>> import os
>>> os.listdir("C:\Python27")
['DLLs', 'Doc', 'include', 'Lib', 'libs', 'LICENSE.txt', 'NEWS.txt', 'python.exe
', 'pythonw.exe', 'README.txt', 'tcl', 'Tools', 'w9xpopen.exe']

Use Powershell - Installed by default on newer versions of Windows (>= Windows 7):

>>> import subprocess
>>> test = subprocess.Popen(['powershell', '/C', 'ls'], stdout=subprocess.PIPE)
>>> out, err = test.communicate()
>>> print out


    Directory: C:\Python27


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        14.05.2013     16:00            DLLs
d----        14.05.2013     16:01            Doc
[..]

Shell commands using cmd.exe would be something like this:

test = subprocess.Popen(['cmd', '/C', 'ipconfig'], stdout=subprocess.PIPE)

For more information see:
The ever useful and neat subprocess module - Launch commands in a terminal emulator - Windows


Notes:

Cloistral answered 14/5, 2013 at 13:50 Comment(16)
I still get the same windows error.. :(Backdrop
@user2371187 I run Python on Linux, but could you try my last edit? Popen('cmd', '/C', 'ls')?Cloistral
@Cloistral There's no ls binary on Windows by default, nor a command of that name in cmd.exe. There is one in powershell.exe, although its output differs significantly from that of Unix's ls. os.listdir() is probably the simplest way to replicate ls on Windows.Infallibilism
@Infallibilism Oh, right of course. Been a while since I used cmd.exe. I'll update my answer.Cloistral
@Cloistral FWIW, subprocess.Popen(['powershell', '/C', 'ls']) will work, but it'd a pain in the butt to parse the output.Infallibilism
Yes I tried it, when I printed it out I got " <subprocess.Popen object at 0x0256FC10>Backdrop
@Infallibilism Thanks, updated my answer again. I would dare to parse it either, it looks like a total mess when I try it.Cloistral
@user2371187 I updated my answer, you should use stdout=subprocess.PIPE. But again, you should really just use os.listdir().Cloistral
@Cloistral I still get some hex base address, I don't know if thats right or not but that's what im getting lolBackdrop
@user2371187 Then you're doing something wrong. I just tested and it works just fine. Note that it's just like the first block of code, just replacing the subprocess.Popen() call: bpaste.net/show/0xpzCvFXaMdFcvazclI4Cloistral
@Cloistral Yeah, nows its just running forever and not stopping... I have no clue lol, I have the exact same code as youBackdrop
@user2371187 I tried both using the Python interpreter/shell and python.exe ls.py in cmd.exe, and it both works fine on Windows 7 x64. Which version do you have? Do you even have Powershell? Test with typing powershell in cmd.exeCloistral
@timiss: The same thing happens to me: PowerShell takes about 50 hours to load. It seems to be an issue on some PCs. And I have version 3.0.Rambort
@Rambort Wouldn't suprise me, but it's actually fast for me even with a superfragmented hard drive and all. But again, no reason to actually use Powershell for ls. If ls is just an example, maybe cmd.exe could work instead (if OP wants to execute a shell command).Cloistral
@user2371187 I can see that you made a new question. Feel free to mark the answer as accepted if you feel this answer solved this question (even though I can see that you did also use shell=True).Cloistral
@timss: I don't know what the speed problem lies in, but I have already seen two other PCs that have that problem. Lucky you! That's the only reason I don't like Powershell.Rambort
R
0

A agree with timss; Windows has no ls command. If you want a directory listing like ls on Windows use dir /B for single-column or dir /w /B for multi-column. Or just use os.listdir. If you do use dir, you must start subprocess using subprocess.Popen(['dir', '/b'], shell=True). If you want to store the output, use subprocess.Popen(['dir', '/b'], shell=True, stdout=subprocess.PIPE). And, the reason I used shell=True is that, since dir is an internal DOS command, the shell must be used to call it. The /b strips the header, and the /w forces multi-column output.

Rambort answered 14/5, 2013 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.