Python-subprocess.anrufen funktioniert aber Teilprozess.check_call nicht - was sind die Unterschiede?
Ich bin mit Python 2.7
Ich versuche zu laufen, ein StatTransfer Programm von Python.
Wenn ich versuche:
tempname = os.path.abspath('./text.txt')
TEMPFILE = open(tempname, 'wb')
try:
subprocess.check_call('ST convert.stc', shell = True, stdout = TEMPFILE, stderr = TEMPFILE)
except:
raise CritError(messages.crit_error_bad_command)
scheitert es (die CritError ist Benutzer-definiert).
Den traceback nicht mir sagen, alles, was nützlich:
Traceback (most recent call last):
File "C:\...\py\run_program.py", line 181, in run_stcmd
run.execute_run(current_directory, posix_command, nt_command)
File "C:\...\py\private\runprogramdirective.py", line 99, in execute_run
raise CritError(messages.crit_error_bad_command)
CritError: 'ERROR! Cannot execute command'
Jedoch die änderung der entsprechenden Zeile in:
subprocess.call('ST convert.stc', shell = True, stdout = TEMPFILE, stderr = TEMPFILE)
erfolgreich ausgeführt.
Das lustige an der Sache ist, ich sehe die gleiche Sache in meinem TEMPFILE für beide Fälle:
|/-|/-|/-|/-|/- |/-|/-|/-|/-|/- Stat/Transfer - Command Processor (c) 1986-2011 Circle Systems, Inc.
www.stattransfer.com
Version 10.1.1866.0714 (32 Bit) - 64 Bit Windows
Serial: ADR4H-L3A3A-N8RJ
User: XXXXXXXXXXX
Your license is in its grace period -- Please call Circle Systems
Your program will die at the end of the month
Status: Temporarily OK (Expired May 31, 2012)
Transferring from SPSS Portable File: ..\orig\10908970\ICPSR_03775\DS0001\03775-0001- Data.por
Input file has 26 variables
Optimizing...
Transferring to Stata: ..\data\ABCFeb.dta
504 cases were transferred(0.02 seconds)
Beachten Sie, dass, wenn ich "st " konvertieren".stc" über die Befehlszeile in Windows, es läuft einfach gut und gibt mir die gleichen log-Nachricht vor. Es hat erreichen, was innen geschrieben konvertieren.stc.
Dies deutet darauf hin, dass die StatTransfer Programm als Unterprozess.check_call. Es ist jedoch ein Fehler am Ende. Welche Art von Fehler ist das??? Wie vermeide ich es? Welche 2 Befehle soll ich benutzen und warum?
ETA: Folgende mgilson unten, ich wieder den Wert von Teilprozess.Anruf bekommen und -1. Was bedeutet das? Warum haben Sie das Programm noch laufen und ich schien nicht zu bemerken, die wirklichen Fehler?
Mögliche Erklärungen und Vorschläge, wie ich das machen soll das hier?
Dank.
- Sollten Sie post von der gesamten traceback -- z.B. welche Zeile den Fehler verursacht. Try/except-Klausel ist wahrscheinlich auch die Maskierung das problem, weil Sie fangen, was auch immer der Fehler ist passiert, und dann heben Sie etwas anderes (ohne Argumente)
- Sorry für die Ausnahme-Klausel. Ich hatte ursprünglich einen Benutzer-definierten. Es tut mir nicht sagen, alles ist nützlich, aber, dass der Subprozess-Aufruf fehlschlägt - das ist alles. Frage aktualisiert.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was wahrscheinlich geschieht, ist, dass Ihr Prozess beendet mit einem nicht-null exit status. Zu überprüfen, führen Sie mit
retcode=subprocess.call(...)
und drucken Sie dannretcode
.subprocess.check_call
wird eine Ausnahme ausgelöst, wennretcode
(oben) ist nicht-null.Ausnahme, die Sie sehen, von der
raise subprocess.CalledProcessError
im try/except-Klausel:BEARBEITEN
Ich würde noch re-schreiben der try/except-Klausel, wie Sie sind, fangen eine Ausnahme und werfen anderen (was bedeutet, dass alle Informationen in der ursprünglichen Nachricht verloren).
Probieren Sie etwas wie:
Diese immer noch geben Ihnen einige (nicht alle) der Informationen aus der ursprünglichen Nachricht. Das problem ist wohl noch, dass Ihr das Unterprogramm beendet mit einem nicht-null exit-code. Vielleicht ist das ok (überprüfen, um zu sehen, dass es erreicht, was Sie wollen, es zu tun).
Sagte Sie, dass Sie können führen Sie den Befehl aus der Kommandozeile, und es sieht alles OK aus. Sie können überprüfen lassen, ob das Verhalten identisch ist, durch die überprüfung der exit-status von der windows-Kommandozeile sowie ( Wie bekomme ich die Anwendung exit-code von einer Windows-Befehlszeile? ). Ich vermute, der exit-status wird noch werden, -1-Wenn es nicht, Ihr Programm ist die Interaktion mit der Umgebung (z.B. Umgebungsvariablen), die sind irgendwie anders, wenn Sie es aufrufen mit python.
Letztlich, wenn das Programm das tut, was Sie wollen, es zu tun, und Sie kümmern sich nicht um den exit-status, dann sollten Sie nur mit
subprocess.call
, aber ich würde vorschlagen, die Beratung, die Anleitung für die Programme, die exit-codes und sehen Sie, was ein Rückgabewert von -1 bedeutet eigentlich.raise UserError("Some message")
. So weit wie, ob oder nicht es ist wirklich ein Fehler ist, hängt das Programm. Ihr Programm ist die Rückgabe -1. Es ist standard für ein Programm return 0 bei Erfolg, was bedeutet, dass das Programm, das Sie aufrufen, ist wohl mit einigen problem (oder es zumindest denkt, es ist). Was -1 bedeutet ganz spezifische Programm, so kann ich nicht geben Ihnen jede Hilfe. Konsultieren Sie das Handbuch für dieses Programm, denke ich.try/except
block (es sei denn, Sie fangen, wenn Sie woanders hin). Alternativ, inexcept
setzen Sie einfachraise
. Das wird die exception erneut ausgelöst. Nachdem Sie haben gedebuggt, können Sie ersetzen, dassraise
mit, was Sie wollen.