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).
CodePudding user response:
Why are you redirecting errors to STDOUT
if you don't want to show the output? For it to end up on the stdout
filehandle of the process object, you want PIPE
, but if you don't care what it is, just send it to DEVNULL
.
Tangentially, you should avoid the bare Popen
when what you want can be accomplished with subprocess.run
or subprocess.check_output
.
output = subprocess.check_output(
['git', 'clone', 'https://some-url.git'],
# perhaps
stdin=DEVNULL, stderr=DEVNULL)
shell=False
is already the default, so you don't need to specify that.
check_output
will raise an error if the git
command fails; you might want to wrap that in try
/except
, or perhaps revert to subprocess.run
which gives you more control over these details.
Tangentially, perhaps note that git
may separately run ssh
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
.
CodePudding user response:
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:
from subprocess import Popen, PIPE, STDOUT, DEVNULL
process = Popen(['setsid', 'git', 'clone', 'https://some-url.git'], stdout = PIPE)
for line in process.stdout:
print(line.decode())
process.wait()