问题
I'm doing a GIT hook in Python 3.5. The python script calls a Bash script that that reads input from the user using read
command.
The bash script by itself works, also when calling directly the python script, but when GIT runs the hook written in Python, it doesn't work as expected because no user input is requested from the user.
Bash script:
#!/usr/bin/env bash
echo -n "Question? [Y/n]: "
read REPLY
GIT Hook (Python script):
#!/usr/bin/env python3
from subprocess import Popen, PIPE
proc = Popen('/path/to/myscript.sh', shell=True, stderr=PIPE, stdout=PIPE)
stdout_raw, stderr_raw= proc.communicate()
When I execute the Python script, Bash's read
does not seem to be waiting for an input, and I only get:
b'\nQuestion? [Y/n]: \n'
How to let the bash script read input when being called from Python?
回答1:
It turns out the problem had nothing to do with Python: if the GIT hook called a bash script it also failed to ask for input.
The solution I found is given here.
Basically, the solution is to add the following to the bash script before the read
:
# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty
In my case, I also had to call the bash process simply like Popen(mybashscript)
instead of Popen(mybashscript, shell=True, stderr=PIPE, stdout=PIPE))
, so the script can freely output to STDOUT and not get captured in a PIPE.
Alternatively, I didn't modify the bash script and instead used in Python:
sys.stdin = open("/dev/tty", "r")
proc = Popen(h, stdin=sys.stdin)
which is also suggested in the comments of the aforementioned link.
回答2:
Adding
print(stdout_raw)
print(stderr_raw)
Shows
b''
b'/bin/sh: myscript.sh: command not found\n'
here. Adding ./ to the myscript.sh worked for the READ once python could find the script. cwd='.' in Popen may also work.
回答3:
This is what worked for me without invoking a bash script from within python. It is a modified version from arod's answer.
import subprocess
import sys
sys.stdin = open("/dev/tty", "r")
user_input = subprocess.check_output("read -p \"Please give your input: \" userinput && echo \"$userinput\"", shell=True, stdin=sys.stdin).rstrip()
print(user_input)
来源:https://stackoverflow.com/questions/46009781/git-hook-python-bash-how-to-read-user-input