2017-02-01 1 views
1

Ich habe ein Python-Programm, das direkt von Jenkins ausgeführt wird. Dieses Programm verwendet die Bibliothek sh, um über diese Funktion einen Andock-Container auszuführen. Beachten Sie, dass es ein wichtiges Merkmal dieser Funktion ist, dass sie den Ausgang des subprocess anzuzeigen, wie sie ausführt:Python: läuft Andockfensters Behälter mit SH und Handhabung UTF-8-Dekodierungsfehler

def run_command(*args, **kwargs): 

    # pass the parent stream 'tty' state to the command: 
    tty_in = sys.stdin.isatty() 
    tty_out = sys.stdout.isatty() 

    run = sh.Command(args[0]) 
    try: 
     for line in run(args[1:], _err=sys.stdout, _iter=True, _tty_in=tty_in, _tty_out=tty_out): 
      sys.stdout.write(line) 
      sys.stdout.flush() 

sich nach den Kommentaren, docker run erfordert eine TTY für die Eingabe, so das Schlüsselwort Argument _tty_in entsprechend eingestellt ist unabhängig von der Zustand von stdin ist. Wenn es jedoch unter Jenkins läuft, ist es False.

aber das Problem ist, um UTF-8 kodierten Fehlermeldungen von Programmen innerhalb des Behälters wie cp laufen. Dies führt zu Fehlern wie:

cp: cannot stat \xe2\x80\x98filename... 

Es stellt sich heraus, die drei Bytes utf-8-Codierung für ein spezielles „Zitat“ Zeichen sind, dass cp verwenden mag, wenn das Gebietsschema ist UTF-8. Wenn ich das Gebietsschema manuell auf "C" einstelle, bevor ich cp direkt ausführe, kann ich sehen, dass es stattdessen normal ascii verwendet.

Wenn mein Python-Skript dieser Fehler trifft, stirbt es mit dem folgenden:

Exception in thread Thread-10: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner 
    self.run() 
    File "/usr/lib/python2.7/threading.py", line 763, in run 
    self.__target(*self.__args, **self.__kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/sh.py", line 1484, in output_thread 
    done = stream.read() 
    File "/usr/local/lib/python2.7/dist-packages/sh.py", line 1974, in read 
    self.write_chunk(chunk) 
    File "/usr/local/lib/python2.7/dist-packages/sh.py", line 1949, in write_chunk 
    self.should_quit = self.process_chunk(chunk) 
    File "/usr/local/lib/python2.7/dist-packages/sh.py", line 1847, in process 
    handler.write(chunk) 
    File "/usr/lib/python2.7/codecs.py", line 351, in write 
    data, consumed = self.encode(object, self.errors) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 16: ordinal not in range(128) 

Dies ist für mich schlägt vor, dass der sh Modul ascii Ausgabe vom subprocess erwartet, aber empfängt UTF-8 und nicht in der Lage ist um es zu entschlüsseln.

fand ich die _encoding und _decode_errors Optionen für sh und obwohl diese das Gebietsschema zu beeinflussen scheint, die cp, wenn sie direkt von sh laufen sieht, scheint es nicht richtig für Programme im Docker Behälter laufen zu übersetzen. Es erlaubt jedoch, dass das Programm fortgesetzt wird, da die Decodierungsfehler übersprungen werden, anstatt eine Ausnahme auszulösen.

würde ich es vorziehen, die Situation besser zu verstehen und eine richtige Lösung zu implementieren. Kann mir jemand erklären, was hier eigentlich passiert, Schritt für Schritt (Jenkins> Python> sh> Docker> Bash)

Ich benutze Python 2.7.12 mit Jenkins 2.33.

+0

Text 'UnicodeDecodeError:‚'bedeutet meistens, dass Konsole/Terminal nicht' UTF-8' nicht verwendet oder nicht Python weiß es und es verwendet 'encode ('ascii')' anstelle von 'encode ('utf-8')' also müssen Sie es manuell tun, wenn Sie eine Zeichenfolge an die Konsole senden. – furas

+0

BTW: immer ** FULL ** Fehlermeldung (Traceback) in ** FRAGE **. Es gibt andere nützliche Informationen, d. Welche Linie macht ein Problem? – furas

+0

@furas danke, habe ich bearbeitet, um vollständige Traceback hinzuzufügen. – meowsqueak

Antwort

1

Ich hatte ein ähnliches Problem, wenn in Docker Container Python-Skript ausgeführt wird.

Ich löste das folgende Verfahren.

(Schritt 1) ​​die folgende Zeile in Dockerfile bevor Python Befehl ausführen

ENV LANG C.UTF-8 
Verwandte Themen