python windowsのコマンド実行時のencode - ぶやかー

windowsは・・・
コマンドプロンプトの実行結果(STDOUTやSTDERR)が必要な場合は

  • 最初にsubprocessでchcp 65001を実行しておく(chcp 437のほうが良いかもしれない)
  • localeでエンコード取得
  • subprocessの出力は取得したエンコードを使う

という感じにしておくと少しはましになる。(今のところはまらなくなった)

import os
import subprocess
import locale

class TestClass():
    def __init__(self):
        if os.name == 'nt':
            # windowsの場合、一般エラーなどの表示が端末により英語だったりcp932だったり・・・
            self.locale = f'cp{locale.getlocale()[1]}'

            subprocess.Popen(['chcp.com', '65001'],
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE
                             ).communicate()

    def test_func(self, src, ttl, timeout, dst):
        ping_cmd_params = ['ping', '-S', src,  '-i',
                            ttl+1,  '-w', timeout, '-n', '1', dst]

        win_cmd = subprocess.Popen(map(str, ping_cmd_params),
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE
                                   )
        out, error = win_cmd.communicate()

        for i in out.decode(self.locale).rstrip("\n").split("\n"):
            print(i)

はまりどころ

sys.stdout.encodingutf-8になってても、
処理によってはcp932で出力されるものがある・・・
わけがわからないよ。

>>> import sys
>>> sys.getfilesystemencoding()
'utf-8'
>>> sys.stdout.encoding
'utf-8'

この状態でも、一般エラーとかはcp932で出力される場合があってutf-8でdecodeしてるとエラーになったりする・・・

localeで取得したエンコードつかってdecodeした方がよい。

>>> import locale
>>> locale.getlocale()
('Japanese_Japan', '932')
>>>

一般エラーの例

windowsのbuildは同じなのに環境によって出力は違う・・・

(venv) PS C:\opt\work\phy\booyaka> python tmp/hoge.py     

Pinging 192.0.2.4 from 192.0.2.1 with 32 bytes of data:
PING: transmit failed. 一般エラーです。

Ping statistics for 192.0.2.4:
    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
(venv) PS C:\opt\work\python\booyaka> python tmp/hoge.py

Pinging 192.0.2.4 from 192.0.2.1 with 32 bytes of data:
PING: transmit failed. General failure.

Ping statistics for 192.0.2.4:
    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

この記事を書いた人 Wrote this article

kmatsunuma

TOP