2017-09-02 2 views
1

Ich mache einen GIT-Hook in Python 3.5. Das Python-Skript ruft ein Bash-Skript auf, das Eingaben vom Benutzer mit dem Befehl read liest.GIT Hook -> Python -> Bash: Wie Benutzereingaben lesen?

Das Bash-Skript selbst funktioniert auch beim Aufruf des Python-Skripts, aber wenn GIT den in Python geschriebenen Hook ausführt, funktioniert es nicht wie erwartet, da vom Benutzer keine Benutzereingabe angefordert wird.

Bash-Skript:

#!/usr/bin/env bash 

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

GIT Hook (Python-Skript):

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

Wenn ich das Python-Skript ausführen, Bash read nicht auf eine Eingabe warten zu sein scheint, und ich nur erhalten:

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

Wie der bash-Skript Eingang lesen lassen, wenn sie von Python genannt zu werden?

+0

@DYZ> das sollte das Standardverhalten sein: * "Mit den Standardeinstellungen von None wird keine Umleitung erfolgen; Die Datei-Handles des Kindes werden vom Elternteil übernommen. "* – spectras

+0

@DYZ Hinzufügen von' stdin = sys.stdin' scheint nichts zu tun ... immer noch keine Eingabeeingabe möglich – arod

+0

@arod> Kopieren Sie den Code, und funktioniert gut hier, vorausgesetzt, '.' ist in '$ PATH' (das ist eine schlechte Idee, obwohl Sie das nicht tun sollten) – spectras

Antwort

0

Es stellte sich heraus, dass das Problem nichts mit Python zu tun hatte: Wenn der GIT-Hook ein Bash-Skript aufgerufen hatte, konnte er auch nicht nach Eingabe fragen.

Die Lösung, die ich gefunden habe, wird here gegeben.

Grundsätzlich ist die Lösung, die die folgenden auf die Bash-Skript vor dem read hinzuzufügen:

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

In meinem Fall musste ich auch statt Popen(mybashscript, shell=True, stderr=PIPE, stdout=PIPE)) wie Popen(mybashscript) einfach die Bash-Prozess aufrufen, so dass das Skript kann frei zu STDOUT ausgeben und nicht in einem PIPE gefangen werden.

Alternativ habe ich nicht die Bash-Skript ändern und stattdessen in Python verwendet:

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

, die auch in den Kommentaren der eingangs genannten Link vorgeschlagen wird.

1

Hinzufügen

print(stdout_raw) 
print(stderr_raw) 

Zeigt

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

hier. Das Hinzufügen von ./ zu myscript.sh funktionierte für das READ, sobald Python das Skript finden konnte. cwd = '.' in Popen kann auch arbeiten.

+0

eigentlich 'myscript.sh' war ein Beispiel, es ist wirklich ein absoluter Pfad'/myscript.sh' ... funktioniert immer noch nicht. Ich habe die Frage korrigiert. – arod

+0

Hmm, haben Sie versucht, eine andere Form des Lesens von stdin, außer bash? Das scheint kurios. Wie die Spektren kommentiert, funktioniert der Code hier gut (Fedora 24, Python 3.5.3). Ich habe es mit einem kleinen C-Fgets-Test versucht, das hat auch funktioniert. –

+0

Sie haben Recht, dass beim direkten Aufruf des Skripts OK funktioniert hat. Ich habe die Frage aktualisiert, indem ich das Detail, dass das Python-Skript von einem GIT-Hook aufgerufen wird, hinzufüge. – arod

Verwandte Themen