How to run bash commands using subprocess.run on windows

Viewed 11667

I want to run shell scripts and git-bash commands using subprocess.run(), in python 3.7.4. When I run the simple example on the subprocess documentation page this happens:

import subprocess

subprocess.run(["ls", "-l"])

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\pycharm\project\envs\lib\subprocess.py", line 472, in run
    with Popen(*popenargs, **kwargs) as process:
  File "C:\pycharm\project\envs\lib\subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "C:\pycharm\project\envs\lib\subprocess.py", line 1178, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified


# it also fails with shell=True
subprocess.call(["ls", "-l"], shell=True)

'ls' is not recognized as an internal or external command,
operable program or batch file.
1

The message from shell=True is a message from windows cmd, which suggests subprocess is not sending commands to git-bash.

I am using a conda environment located in the project/envs/ folder for python. I have also installed git-bash.

I also tried setting the env and got the same error.

import os
import subprocess

my_env = os.environ.copy()
my_env["PATH"] = 'C:\Program Files\Git\;' + my_env["PATH"]
subprocess.run(['git-bash.exe', 'ls', '-l'], env=my_env)

Traceback (most recent call last):
  File "<input>", line 3, in <module>
  File "C:\pycharm\project\envs\lib\subprocess.py", line 472, in run
    with Popen(*popenargs, **kwargs) as process:
  File "C:\pycharm\project\envs\lib\subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "C:n\pycharm\project\envs\lib\subprocess.py", line 1178, in _execute_child
    startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified

I can get it to run by pointing at the git-bash.exe, but it returns an empty string instead of the files in my directory

import subprocess
subprocess.run(['C:\Program Files\Git\git-bash.exe', 'ls', '-l'], capture_output=True)

CompletedProcess(args=['C:\\Program Files\\Git\\git-bash.exe', 'ls', '-l'], returncode=0, stdout=b'', stderr=b'')


I would appreciate any advice on the best way to get this working as shown on the subprocess documentation page.

4 Answers

I found that I can run commands using ...Git\bin\bash.exe instead of the ...\Git\git-bash.exe, like this:

import subprocess
subprocess.run(['C:\Program Files\Git\\bin\\bash.exe', '-c','ls'], stdout=subprocess.PIPE)

CompletedProcess(args=['C:\\Program Files\\Git\\bin\\bash.exe', '-c', 'ls'], returncode=0, stdout=b'README.md\n__pycache__\nconda_create.sh\nenvs\nmain.py\ntest.sh\nzipped\n')

Try this

p = subprocess.Popen(("ls", "-l"), stdout=subprocess.PIPE)
nodes = subprocess.check_output(("grep"), stdin=p.stdout)
p.wait()
  • ls is Linux shell command for listing files and directories
  • dir is Windows command line command for listing files and directories

Try to run dir in Windows command line. If it works, try to run the same command using python subprocess:

import subprocess

subprocess.run(["dir"])

For a machine with Windows Operating System, Try the following

import subprocess
subprocess.run(["dir", "/p"], shell=True)

"ls" is replaced with "dir", "-l" is replaced with "/l" and the "shell" is set to true

For a machine with Linux/Mac Operating System, Try the following

import subprocess
subprocess.run(["ls", "-l"])
Related