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)
我在 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)