python subprocess encoding

2019-07-25 18:47发布

问题:

I'm trying to store the output of powershell in a var:

import subprocess
subprocess.check_call("powershell \"Get-ChildItem -LiteralPath 'HKLM:SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall' -ErrorAction 'Stop' -ErrorVariable '+ErrorUninstallKeyPath'\"", shell=True, stderr=subprocess.STDOUT)

this way, using check_call, it prints ok, for example:

DisplayName : Skype™

but this way it only prints to screen, so i have to use

import subprocess
output = subprocess.check_output("powershell \"Get-ChildItem -LiteralPath 'HKLM:SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall' -ErrorAction 'Stop' -ErrorVariable '+ErrorUninstallKeyPath'\"", shell=True, stderr=subprocess.STDOUT)

but then, using check_output, i get:

DisplayName : SkypeT

how can i work around this?

回答1:

The output is a of type bytes so you need to either decode it to a string with .decode('utf-8') (or with whatever codec you want), or use str(), Example:

import subprocess
output_bytes = subprocess.check_output("powershell \"Get-ChildItem -LiteralPath 'HKLM:SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall' -ErrorAction 'Stop' -ErrorVariable '+ErrorUninstallKeyPath'\"", shell=True, stderr=subprocess.STDOUT)

output_string = str(output_bytes)
# alternatively
# output_string = output_bytes.decode('utf-8')

# there are lots of \r\n in the output I encounterd, so you can split
# to get a list
output_list = output_string.split(r'\r\n')

# once you have a list, you can loop thru and print (or whatever you want)
for e in output_list:
    print(e)

The key here is to decode to whatever codec you want to use in order to produce the correct character when printing.



回答2:

Following this post instructions:How to make Unicode charset in cmd.exe by default?

Its possible to bypass this encoding problem

import subprocess
output = subprocess.check_output("chcp 65001 | powershell \"Get-ChildItem -LiteralPath 'HKLM:SOFTWARE\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Uninstall' -ErrorAction 'Stop' -ErrorVariable '+ErrorUninstallKeyPath'\"", shell=True, stderr=subprocess.STDOUT)