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)
目次
Outline
はまりどころ
sys.stdout.encoding
でutf-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),