GIT hook -> Python -> Bash: 如何读取用户输入?

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

我在 Python 3.5 中做一个 GIT 挂钩。 python 脚本调用 Bash 脚本,该脚本使用 read 命令读取用户的输入。

bash 脚本本身可以工作,直接调用 python 脚本时也是如此,但是当 GIT 运行 Python 中编写的钩子时,它不会按预期工作,因为没有请求用户输入。

Bash 脚本:

#!/usr/bin/env bash

echo -n "Question? [Y/n]: "
read REPLY

GIT 挂钩(Python 脚本):

#!/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()

当我执行Python脚本时,Bash的read似乎没有等待输入,我只得到:

b'\nQuestion? [Y/n]: \n'

如何让 bash 脚本在被 Python 调用时读取输入?

添加

print(stdout_raw)
print(stderr_raw)

演出

b''
b'/bin/sh: myscript.sh: command not found\n'

在这里。将 ./ 添加到 myscript.sh 对 READ 有效,一旦 python 可以找到脚本。 cwd='.'在 Popen 中也可以工作。

事实证明问题与 Python 无关:如果 GIT 挂钩调用了 bash 脚本,它也无法请求输入。

我找到的解决方案是here

基本上,解决方案是在 read 之前的 bash 脚本中添加以下内容:

# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty

在我的例子中,我还必须像 Popen(mybashscript) 一样简单地调用 bash 进程而不是 Popen(mybashscript, shell=True, stderr=PIPE, stdout=PIPE)),因此脚本可以自由输出到 STDOUT 而不会被捕获管道。

或者,我没有修改 bash 脚本,而是在 Python:

中使用
sys.stdin = open("/dev/tty", "r")
proc = Popen(h, stdin=sys.stdin)

在上述link.

的评论中也有建议

这对我来说很有效,无需从 python 中调用 bash 脚本。它是 arod 回答的修改版本。

    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)