failing to execute git command but os.system does it without issue

I’m running into a bit of a weird issue here.

I’m trying to clone some GitHub repositories automatically but I’m seeing error out in cases where os.system, or just running the command directly in my shell, works fine.

This is the command I’m trying to run:'GIT_TERMINAL_PROMPT=0 git clone'.split())

Which leads to this error:

>>>'GIT_TERMINAL_PROMPT=0 git clone'.split())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/omermikhailk/.pyenv/versions/3.11.0/lib/python3.11/", line 546, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/Users/omermikhailk/.pyenv/versions/3.11.0/lib/python3.11/", line 1022, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/Users/omermikhailk/.pyenv/versions/3.11.0/lib/python3.11/", line 1899, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'GIT_TERMINAL_PROMPT=0'

When the result should be what os.system gives:

>>> os.system('GIT_TERMINAL_PROMPT=0 git clone')
Cloning into 'fake-repo'...
fatal: could not read Username for '': terminal prompts disabled

Would anyone happen to know the reason behind this?

>Solution :

You need to use the following instead:['git', 'clone', ''], env={'GIT_TERMINAL_PROMPT': '0'})

When you run a command via subprocess, you are not using bash or sh or any shell, so environment variables are not interpreted, and must be specified via env, not the CLI.

Note that it is the best practice to explicitly craft the list for the command and its arguments yourself, rather than using a string and .split(). If you have any arguments that contain spaces, rather than including literal quotes in the string that you pass as a list element, you would use a string that contains the full argument. I.e., NOT ['echo', '"foo', 'bar"'] (which would be the result of .split()), but ['echo', 'foo bar'] to include the space.

Another note as to why this occurs is that does technically allow you to pass shell=True, but you should avoid doing so at all costs due to security implications if you are working with any content that may be user-generated. The best practice is to use env={...} as suggested.

If you need to include current environment variables, then you can use the following:

from os import environ

env = environ.copy()
env['GIT_TERMINAL_PROMPT'] = '0'['git', 'clone', ''], env=env)

Leave a Reply