GIT hook -> Python -> Bash: How to read user input?

心不动则不痛 提交于 2020-07-22 04:41:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!