Python: Reagieren Sie auf Befehlszeile Aufgefordert
Ich versuche die Verwendung von Python für die Interaktion mit einem anderen Programm über die Kommandozeile. Das Hauptproblem was ich habe ist ein spezifischer Aufruf mit mehreren follow-up-Aufforderungen. Zuerst die Kommandozeile aufrufen, fragt nach dem Namen eines Projekts, und geht dann zu Fragen, ob ich möchte den Unterordner des Projekts. Ich brauche die Antwort J/n jede dieser in Ordnung ist und die Antwort auf jede ist leider nicht all y oder n sein. Darüber hinaus kann ich nicht wissen, die Antwort auf die Frage Lesen, ohne die einzelnen fordert, so bin ich unfähig, Sie senden einen block von 'y' s oder 'n alle auf einmal.
Dies ist der Aufruf:
si viewproject
Nach Eingabe des Befehls die Kommandozeile aufgefordert:
Geben Sie den Namen des Projekts:
Sowie ein Beispiel-Antwort wäre:
Geben Sie den Namen des Projekts: c:/test.pj
Nach der Eingabe des Projekts, werden Sie aufgefordert, die folgenden:
Wollen Sie recurse-in das Teilprojekt test_subprj.pj? [ynYN](n)
An dem Punkt muss ich reagieren, entweder mit y oder n, je nachdem, ob ich brauche das Teilprojekt. Wieder, die Antwort auf diese Frage ist abhängig von dem Teilprojekt. Ich muss in der Lage sein zu Lesen das Teilprojekt in dieser Eingabeaufforderung, um darauf zu reagieren mit einem 'y' oder 'n'
Derzeit muss ich manuell eingeben in das Projekt und jedes der y und n jeweils. Mein Ziel ist es, diesen Prozess zu automatisieren mit Python.
Gibt es eine Möglichkeit, zu reagieren, um diese Befehlszeile Eingabeaufforderungen automatisch?
Aktuellen Fortschritt
Teilprozess Strategie
project_path = "c:/test.pj"
with Popen(["si", "viewproject", "--project=" + project_path],
stdin=PIPE, stdout=PIPE, universal_newlines=True) as p:
for line in p.stdout:
if line.startswith("Do you want"):
answer = 'n'
else:
continue # skip it
print(answer, file=p.stdin) # provide answer
p.stdin.flush()
Dieser Methode hängt nach der mit Popen Anweisung. Es nie Fehler, aber es niemals betreten oder verlassen der for-Anweisung und nie abgeschlossen ist. Ich bin aktuell ausfallenden Antworten auf "n", aber das wird ersetzt durch die Logik später.
Winpexpect Strategie
import re
import sys
from functools import partial
import winpexpect
project_path = "c:/test.pj"
p = winpexpect.winspawn('si viewproject --project=' + project_path)
p.logfile = sys.stdout
patterns = [re.compile('ynYN'), winpexpect.EOF]
for found in iter(partial(p.expect, patterns), 1): # until EOF
if found == 0:
answer = 'n'
p.sendline(answer)
Gibt folgende Fehlermeldung:
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\winpexpect.py", line 541, in read_nonblocking
handle, status, data = self.child_output.get(timeout=timeout)
File "C:\Python33\lib\queue.py", line 175, in get
raise Empty
queue.Empty
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\pexpect.py", line 1378, in expect_loop
c = self.read_nonblocking (self.maxread, timeout)
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\winpexpect.py", line 543, in read_nonblocking
raise TIMEOUT('Timeout exceeded in read_nonblocking().')
pexpect.TIMEOUT: Timeout exceeded in read_nonblocking().
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "K:\eclipse_3.6.0\plugins\org.python.pydev_2.6.0.2012062818\pysrc\pydev_runfiles.py", line 432, in __get_module_from_str
mod = __import__(modname)
File "C:\workspace\Test_prj\Test_prj.py", line 19, in <module>
for found in iter(partial(p.expect, patterns), 1): # until EOF
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\pexpect.py", line 1311, in expect
return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\pexpect.py", line 1325, in expect_list
return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize)
File "C:\Python33\lib\site-packages\winpexpect-1.5-py3.3.egg\pexpect.py", line 1409, in expect_loop
raise TIMEOUT (str(e) + '\n' + str(self))
pexpect.TIMEOUT: Timeout exceeded in read_nonblocking().
<winpexpect.winspawn object at 0x0144AE50>
version: 2.3 ($Revision: 399 $)
command: si
args: ['si', 'viewproject', '--project=c:/test.pj']
searcher: searcher_re:
0: re.compile("ynYN")
1: EOF
buffer (last 100 chars):
before (last 100 chars):
after: <class 'pexpect.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 6448
child_fd: 4
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='Cp1252'>
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
ERROR: Module: Test_prj could not be imported (file: C:\workspace\Test_prj\Test_prj.py).
Installieren Winpexpect
Faul Personen Weg
Optional: Installieren Sie Die Nase
Optional: Installation Von Pip
Erste-Welt-Probleme
Python ist eine neue Sprache für mich, und ich hatte noch nie installiert ein Paket vor für Python. Zusätzlich Python 3.x ist ein wenig anders als die anderen Versionen der Python-Installation machen Module, die ein wenig mehr Abenteuer.
So, anderen zu helfen, erhalten einige süße, süße-Modul-Aktion (und zu helfen, diejenigen, die mehr wissen sehen, ob ich etwas getan habe falsch) hier ist ein bald Erfolgsgeschichte (hoffentlich) dokumentieren, wie ich und installierte mein erstes Modul.
Setup
Python ermöglicht third-party-Gruppen zu entwickeln und zu vertreiben Module zur Erweiterung der Fähigkeiten der Programmiersprache. Natürlich, es ist ein standard-Weg, um zu helfen third-party-Entwickler Module so leicht verfügbar, um den end-Benutzer wie möglich.
Für Python 3.x, der standard für die Verteilung von Modulen namens Distutils.
Hier ist, wie ein Entwickler verwendet Distutils:
Verteilen Von Python Modulen
Und hier ist, wie der Endbenutzer verwendet, Distutils:
Installation Von Python-Modulen
Normalerweise navigieren Sie zu dem Ordner, der heruntergeladene Modul in der Kommandozeile zum laufen "setup.py installieren Sie" genug sein.
ABER
Manchmal Leben ist nicht so einfach und man kann immer noch haben Sie Probleme mit Ihrer installation. Sie kann in der Tat etwas anderes brauchen. Zum Beispiel, erhalten Sie möglicherweise die folgende Fehlermeldung:
"ImportError "No Modul named Setuptools""
Glücklicherweise gibt es eine Lösung dafür:
Python 3: ImportError "No Modul named Setuptools"
Als es stellt sich heraus, nicht alles verwendet distutils. Einige Pakete verwenden setuptools. Leider gibt es keine setuptools Python 3.x. Vielmehr Python 3.x verwendet zu verteilen, die ein Zweig der setuptools.
Also für diejenigen, die die Verwendung von Python 3.x ist hier Verteilen: Verteilen
Für diejenigen, die mit Python 2.x, hier ist Setuptools: Setuptools
In die Installationsanleitung zu Verteilen, es sagt der folgende:
"Download
distribute_setup.py <http://python-distribute.org/distribute_setup.py>
_
und führen Sie mit Hilfe der Python-interpreter deiner Wahl."
Er sagt auch: "Bemerken Sie diese Datei ist auch in der source-Version."
Also ich heruntergeladen Verteilen und gespeichert auf dem computer. Einmal war es auf dem computer gespeichert, ich lief distribute_setup.py von der source-Version und bekam die folgende Fehlermeldung:
Downloading http://pypi.python.org/packages/source/d/distribute/distribute-0.6.36.tar.gz
Traceback (most recent call last):
File "C:\Python33\lib\urllib\request.py", line 1252, in do_open
h.request(req.get_method(), req.selector, req.data, headers) File "C:\Python33\lib\http\client.py", line 1049, in request
self._send_request(method, url, body, headers)
File "C:\Python33\lib\http\client.py", line 1087, in _send_request
self.endheaders(body)
File "C:\Python33\lib\http\client.py", line 1045, in endheaders
self._send_output(message_body)
File "C:\Python33\lib\http\client.py", line 890, in _send_output
self.send(msg)
File "C:\Python33\lib\http\client.py", line 828, in send
self.connect()
File "C:\Python33\lib\http\client.py", line 806, in connect
self.timeout, self.source_address)
File "C:\Python33\lib\socket.py", line 406, in create_connection
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
socket.gaierror: [Errno 11001] getaddrinfo failed
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\workspace\PythonTest\distribute_setup.py", line 553, in <module>
sys.exit(main())
File "C:\workspace\PythonTest\distribute_setup.py", line 549, in main
tarball = download_setuptools(download_base=options.download_base)
File "C:\workspace\PythonTest\distribute_setup.py", line 204, in download_setuptools
src = urlopen(url)
File "C:\Python33\lib\urllib\request.py", line 160, in urlopen
return opener.open(url, data, timeout)
File "C:\Python33\lib\urllib\request.py", line 473, in open
response = self._open(req, data)
File "C:\Python33\lib\urllib\request.py", line 491, in _open
'_open', req)
File "C:\Python33\lib\urllib\request.py", line 451, in _call_chain
result = func(*args)
File "C:\Python33\lib\urllib\request.py", line 1272, in http_open
return self.do_open(http.client.HTTPConnection, req)
File "C:\Python33\lib\urllib\request.py", line 1255, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 11001] getaddrinfo failed>
Gut, dass ist nicht gut! Ganz ehrlich, ich weiß immer noch nicht, wo der Fehler herkommt oder warum es passiert ist.
Egal, dann fand ich die folgende Website, dass ran ein .exe-Datei zu installieren, zu verteilen sowie pip.
Also habe ich diese installiert und dann verwendet Sie die folgende Website, um das setup meinen computer noch einfacher verwenden easy_install: Einrichten Leicht Zu Installieren Leicht Gemacht
Sobald ich diese arbeiten, die ich dann installiert Nase:Nase
Der Grund, ich habe die Nase war, weil die Winpexpect website sagt:
"WinPexpect enthält unit-tests. Um die tests auszuführen, müssen Sie die Nase. Verwenden Sie den folgenden Befehl zum ausführen des tests:
$ python setup.py test"
Gut, das klingt schön :). Jetzt habe ich nur wünschte, ich wusste, wo zu laufen, dass test. Ich weiß, dass, wenn du manuell installieren, die Sie verwenden setup.py install-Befehl, so wird es definitiv sein setup.py in der Zip-Verzeichnis online. Um zu sehen, ob dies korrekt war, die ich heruntergeladen und gespeichert, die winpexpect-Datei, extrahiert die Informationen navigiert werden, um es von der Kommandozeile, und lief setup.py test.
Hier wurde das folgende Ergebnis:
running test
running build_py
running egg_info
creating c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info
writing c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\PKG-INFO
writing dependency_links to c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\dependency_links.txt
writing top-level names to c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\top_level.txt
writing requirements to c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\requires.txt
writing manifest file 'c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\SOURCES.txt'
reading manifest file 'c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\SOURCES.txt'
writing manifest file 'c:\documents and settings\slz1fh\desktop\winpexpect\geertj-winpexpect-76df3cfcb143\build\lib\winpexpect.egg-info\SOURCES.txt'
running build_ext
Traceback (most recent call last):
File "C:\Documents and Settings\SLZ1FH\Desktop\winpexpect\geertj-winpexpect-76df3cfcb143\setup.py", line 35, in <module>
use_2to3 = True
File "C:\Python33\lib\distutils\core.py", line 148, in setup
dist.run_commands()
File "C:\Python33\lib\distutils\dist.py", line 917, in run_commands
self.run_command(cmd)
File "C:\Python33\lib\distutils\dist.py", line 936, in run_command
cmd_obj.run()
File "C:\Python33\lib\site-packages\distribute-0.6.36-py3.3.egg\setuptools\command\test.py", line 138, in run
self.with_project_on_sys_path(self.run_tests)
File "C:\Python33\lib\site-packages\distribute-0.6.36-py3.3.egg\setuptools\command\test.py", line 118, in with_project_on_sys_path
func()
File "C:\Python33\lib\site-packages\distribute-0.6.36-py3.3.egg\setuptools\command\test.py", line 164, in run_tests
testLoader = cks
File "C:\Python33\lib\unittest\main.py", line 124, in __init__
self.parseArgs(argv)
File "C:\Python33\lib\unittest\main.py", line 168, in parseArgs
self.createTests()
File "C:\Python33\lib\unittest\main.py", line 175, in createTests
self.module)
File "C:\Python33\lib\unittest\loader.py", line 137, in loadTestsFromNames
suites = [self.loadTestsFromName(name, module) for name in names]
File "C:\Python33\lib\unittest\loader.py", line 137, in <listcomp>
suites = [self.loadTestsFromName(name, module) for name in names]
File "C:\Python33\lib\unittest\loader.py", line 96, in loadTestsFromName
module = __import__('.'.join(parts_copy))
File "C:\Python33\lib\site-packages\nose-1.3.0-py3.3.egg\nose\__init__.py", line 1, in <module>
from nose.core import collector, main, run, run_exit, runmodule
File "C:\Python33\lib\site-packages\nose-1.3.0-py3.3.egg\nose\core.py", line 143
print "%s version %s" % (os.path.basename(sys.argv[0]), __version__)
^
SyntaxError: invalid syntax
Ok, also die Python-version 3.3 der Nase enthält ungültige syntax für Python 3.3?
print "%s, version %s" % (os.Pfad.basename(sys.argv[0]), version)...
sollte auf jeden Fall Klammern um ihn herum... Das macht mich Frage, ob die Nase tatsächlich arbeiten hier, wie es ganz klar, sieht für die früheren Versionen von Python.
- Was ist Ihr OS und python-version? Funktioniert der Programm-Eingabe - /Ausgabe-Umleitung und verwendet es block-bufferring wenn es nicht interaktiv ausgeführt, z.B., hat die folgenden fehl:
xx viewproject < answers.txt > output.txt
woanswers.txt
enthält jede Antwort auf ein newline? - Mein OS ist Windows XP, meine Python-version ist 3.3. mit xx viewproject <Antworten.txt> output.txt funktioniert einwandfrei. Aber, meine Antworten auf die Kommandozeile aufgefordert werden müssen, basierend auf die Anweisungen selbst. Ich weiß nicht, ob ich brauche, um Rekursion in Unterprojekt, bis ich sehen kann, was Unterprojekt Sie will mich auf recurse-in.
- Wo "ERROR: Module: ..." - Meldung kommt? Wie führe
Test_prj.py
? - Ich bin mit Test_prj.py in einer Eclipse IDE für C/C++ - Entwickler.
- Versuchen Sie, führen Sie es aus-Konsole (cmd.exe) direkt (just in case). Hinweis: es sollten keine
winpexpect
Verzeichnis an der Seite, die das script sonst wird es versuchen, zu importieren, anstatt die installierte version. - das Skript Test_prj ist in der folgenden Position: c:\workspace\Test_prj\Test_prj.py. die winpexpect Verzeichnis ist in C:\Python33\Lib\site-packages\winpexpect-1.5-py3.3.egg\ also die winpexpect Verzeichnis ist nicht neben den anderen. Aber ich habe mir die SOURCES-Datei für winpexpect und Folgendes sah: lib/pexpect.py; lib/winpexpect.py also ich kopiert pexpect.py und winpexpect.py aus C:\Python33\Lib\site-packages\winpexpect-1.5-py3.3.egg\ und legte Sie in C:\Python33\Lib. Das war, wie ich eclipse zum erkennen der import in den ersten Platz.
- "Versuchen Sie, führen Sie es aus-Konsole (cmd.exe) direkt." führt auch immer wieder Zeitüberschreitung.
- Durch kopieren der Dateien, die Sie haben könnten beschädigt (evtl. schon kaputt)
winpexpect
installation. 1. Sie sollten nicht brauchen, um alle Dateien kopieren, wenn die installation erfolgreich ist. 2. wenn es verwendet 2to3-tool während der installation mit dem kopieren der Dateien kann es brechen. 3. Typische installation sollte nur einen Befehl:package-version-...exe
(oder .msi) oderpip install package
- ich werde bis Abstimmung in dieser Frage Grund, Server besser als ein Leitfaden zur python-installation für Neulinge auf dem windows-Umgebung
Du musst angemeldet sein, um einen Kommentar abzugeben.
In die Kommentare, die Sie erwähnt, dass
xx viewproject < answers.txt > output.txt
funktioniert, aber Sie können es nicht verwenden, da die Antworten hängen von der Ausgabe aus dem Teilprozess.Im Allgemeinen
pexpect
-wie-Module wiewinpexpect
(für Windows) kann verwendet werden. So etwas wie:Wenn die Anweisungen enden mit einem Zeilenumbruch (und der Teilprozess nicht Puffern); Sie konnte Lesen, Zeile für Zeile mit
subprocess
Modul direkt:Um zu testen, ob Sie Lesen können, etwas von der
xx
mitsubprocess
:pexpect
funktioniert unter *nix, wenn Sie es brauchen. Sie können nicht.communicate()
denn die Antwort hängt von den Teilprozess output. Wenn die Aufforderungen nicht beendet durch einen Zeilenumbruch, dann müssen Sie zu vervielfältigen/zu implementierenpexpect
-wie code zu Lesen/analysieren Sie und es könnte Probleme z.B., Teilprozess verwenden könnte-block-buffering, wenn es nicht interaktiv ausgeführt.if os.platform == 'nt'
und auf saubere python-Installationen ohne externe Pakete (wenn möglich) also ich bin einfach nur neugierig, was sind die Vorteile.p.before
. Es scheint, wie Ihr script nicht sehen, jede Ausgabe aus dem Kind-Prozess.Ja, zunächst können Sie erstellen Teilprozess als Objekt von:
Dann haben Sie Methoden wie
kommunizieren()
zur Verfügung, zum Beispiel:1 -
os.linesep
Die schicken alle Antworten auf einmal (und hoffentlich werden es genug) sich auf der gleichen Frage zu jeder Zeit.
Können Sie auch versuchen, analysieren
p.stdout
und dann schreibenp.stdin
, aber dies kann einen deadlock verursachen, wenn ein Puffer voll bekommen während der Wartezeit für andere, also seien Sie vorsichtig mit diesem. Zum Glück gibt es einige komplexe Beispiele auf google.Einfache version wäre:
Ich würde auch überlegen umschreiben:
Zu:
Sofern Sie nicht explizit brauchen, Shell-Aufruf.
p.communicate(newline.join(commands))
Für das test-Projekt ich weiß, dass die Versorgung der Befehle von['n', 'n', 'n']
ausreichend zu beantworten, werden alle nachfolgenden Ansagen nach der Bereitstellung der Projekt name.p = subprocess.Popen('si viewproject --project=d:/Projects/test.pj', shell = True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
newline = os.linesep
commands = ['n', 'n', 'n']
p.communicate(newline.join(commands))
Namen des Projekts in den Popen funktioniert, und für das test-Projekt mit den drei 'n sind ausreichend. Unabhängig davon, sind die Fehler aufp.communicate(newline.join(commands))
besteht.Traceback (most recent call last): File "C:\workspace\Subprj_Autogen\Subprj_Autogen.py", line 21, in <module> p.communicate(newline.join(commands)) File "C:\Python33\lib\subprocess.py", line 906, in communicate stdout, stderr = self._communicate(input, endtime, timeout) File "C:\Python33\lib\subprocess.py", line 1180, in _communicate self.stdin.write(input) TypeError: 'str' does not support the buffer interface
Popen(..., universal_newlines=True)
arbeiten mit Unicode-strings statt.