I’m trying to execute an external command from a Python script using the subprocess run method, but I’m running into an error that says the system can’t find the file I’m trying to run.
My goal is pretty simple: I just want to run a command that lists the files in a directory and capture or display the output. However, instead of getting the expected result, Python throws a FileNotFoundError.
Here’s a simplified version of the code I’m using (rewritten example):
import subprocess
subprocess.run(["ls", "-l"])
When I run this on my machine, I get an error indicating that the command can’t be found. I was expecting it to print out the contents of the current directory instead.
Am I using subprocess.run incorrectly here?
Is this an operating system–specific issue, or do I need to configure the command differently (for example, when running on Windows vs Linux/macOS)?
Any explanation or working examples would really help. Thanks!
Hey! I ran into this exact issue before. The main thing to remember is that subprocess.run doesn’t automatically know about shell commands like ls on Windows. On Linux/macOS, ls works fine, but on Windows, there’s no ls command by default. One way to make it work cross-platform is to either use the shell=True argument or switch to a command that exists on your OS. For example, on Windows:
import subprocess
subprocess.run("dir", shell=True)
And on Linux/macOS, your original ls -l works fine:
import subprocess
subprocess.run(["ls", "-l"])
So yes, it’s mostly an OS-specific thing , your command has to exist in the environment where Python is running.
If you want to actually capture the output rather than printing directly, you can use capture_output=True and text=True (Python 3.7+), which I find useful for logging or processing results:
import subprocess
result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
print("Command output:\n", result.stdout)
This also helps debug because if the command fails, you can inspect result.stderr for error messages. I often use this in scripts where I need to check results before proceeding.
In some situations, especially on Windows or custom environments, the command might not be in the PATH. I like to double-check the command path with shutil.which before running it:
import subprocess
import shutil
cmd = "ls"
if shutil.which(cmd) is None:
print(f"Command {cmd} not found!")
else:
subprocess.run([cmd, "-l"])
This way, you can give a friendly error if the command isn’t available instead of hitting a FileNotFoundError. It’s saved me a lot of debugging headaches in cross-platform scripts. Always consider the OS you’re running on and whether the command exists in the PATH. Use shell=True sparingly (mostly for simple commands on Windows), or stick to full paths for external executables when you want your script to be portable.