I’m trying to non-interactively execute a git pull
command with subprocess.Popen
. Specifically, if for some reason git asks for a password, the command should fail. But instead, it asks the password in the shell I run my python program in, and waits for my input, this not what I want.
I also need to capture the output of the command (this is why I use subprocess.Popen
). I have noted that if I use stdout = DEVNULL
then it behaves as I want, excepted I do need to pipe stdout to capture it.
Here is a simplified version of the code I use to execute the command:
from subprocess import Popen, PIPE, STDOUT, DEVNULL
process = Popen(['git', 'clone', 'https://some-url.git'], stdin = DEVNULL, stdout = PIPE)
for line in process.stdout:
print(line.decode())
process.wait()
I’ve also tried with stdin = None
. This parameter seems to have no effect.
I’m executing the python program in a bash console on a Debian 11 system (but I’d like a portable solution).
2
Answers
I've found a way to deal with this issue, by using
setsid
to run the command in a non-interactive session. But this is a Linux thing, I'm still interested if there is a way to solve the issue with python in a portable way (I haven't made any test on Windows yet, maybe the issue doesn't exist there to begin with, but surely setsid won't work).The code would look like this:
Why are you redirecting errors to
STDOUT
if you don’t want to show the output? For it to end up on thestdout
filehandle of the process object, you wantPIPE
, but if you don’t care what it is, just send it toDEVNULL
.Tangentially, you should avoid the bare
Popen
when what you want can be accomplished withsubprocess.run
orsubprocess.check_output
.shell=False
is already the default, so you don’t need to specify that.check_output
will raise an error if thegit
command fails; you might want to wrap that intry
/except
, or perhaps revert tosubprocess.run
which gives you more control over these details.Tangentially, perhaps note that
git
may separately runssh
and generate error output from that e.g. when you connect to a host you have not connected to before. The sustainable solution to that is to specify options for how to handle the connection, perhaps in your.ssh/config
.