使用Python的popen调用时设置powershell编码输出

时间:2016-01-13 09:29:11

标签: python powershell subprocess

我有一个python脚本执行一些powershell脚本(我从cmd或powershell控制台执行python)

import subprocess, json

def readSensorList():
    with open('sensor.json') as json_data:
        data = json.load(json_data)
    json_data.close()
    return data
def executeSensor():
    sensorList = list()
    sensorListRaw = readSensorList()
    for sensor in sensorListRaw["sensors"]:
        x = subprocess.Popen(["powershell.exe",
    '-ExecutionPolicy',
    'Unrestricted', sensorListRaw["path"] + sensor["filename"]], stdout=subprocess.PIPE)
        sensorList.append(x)
    return sensorList
def sortSensorInformation(sensors):
    sortedJson = list()
    for sensor in sensors:
        sortedJson.append(json.loads(sensor.communicate()[0].decode('windows-1252')))
    print(json.dumps(sortedJson))

sortSensorInformation(executeSensor())

PS脚本输出是JSON,但在我试过的不同操作系统中编码永远不会相同...

在我的Windows 10法语中,没有.decode(' windows-1252')我得到:

[b'{\t"AVPath": "%ProgramFiles%\\\\Windows Defender\\\\MSASCui.exe", \t"AVDefStatus": "Up to date", \t"AVName": "Windows Defender", \t"AVRTP": "Enabled"}\r\n', b'{\t"Uptime": "2:0:56:33"}\r\n', b'{\t"updatePending": 2, \t"isARebootPending": false}\r\n', b'{\t"serverAge": ":::"}\r\n', b'{\t"freeSpace": 831.379005432129, \t"diskLetter": "C:", \t"totalSpace": 931.022457122803, \t"volumeName": ""}\r\n', b'{\t"firewallStatus": "OK"}\r\n']

使用.decode(' windows-1252')编码就可以了:

[{"AVRTP": "Enabled", "AVPath": "%ProgramFiles%\\Windows Defender\\MSASCui.exe", "AVName": "Windows Defender", "AVDefStatus": "Up to date"}, {"Uptime": "2:0:54:53"}, {"isARebootPending": false, "updatePending": 2}, {"serverAge": ":::"}, {"diskLetter": "C:", "freeSpace": 831.373157501221, "volumeName": "", "totalSpace": 931.022457122803}, {"firewallStatus": "OK"}]

在服务器2012法语版上,它与Windows 10相同,但在Server 2011法语版上, 用1252解码:

['{\t"Uptime": "49:21:54:10"}\r\n', '{\t"isARebootPending": false,\t"updatePending": 1}\r\n', '[{\t"volumeName": "SYSTEME", \t"freeSpace": 95.5574760437012, \t"totalSpace": 279.266887664795, \t"diskLetter": "C{\t"v\r\nolumeName": "DONNEES", \t"freeSpace": 160.898635864258,\t"totalSpace": 558.877925872803, \t"diskLetter": "D:"},{\t"volume\r\nName": "Backup", \t"freeSpace": 65.9345016479492, \t"totalSpace": 558.877925872803, \t"diskLetter": "Z:"}]\r\n', '{\t"firewallStatus": "OK"}\r\n']

但有时我会:

UnicodeEncodeError: 'charmap' codec can't encode character '\u0160' in position 226: character maps to <undefined>

没有.decode(&#39; windows-1252&#39;)(仍然是2011年法语):

[b'{\t"Uptime": "49:21:51:37"}\r\n', b'{\t"isARebootPending": false, \t"updatePending": 1}\r\n', b'[{\t"volumeName": "SYSTEME", \t"freeSpace": 95.5614395141602, \t"totalSpace": 279.266887664795, \t"diskLetter": "C:"}, {\t"v\r\nolumeName": "DONNEES", \t"freeSpace": 160.899082183838, \t"totalSpace": 558.877925872803, \t"diskLetter": "D:"}, {\t"volume\r\nName":"Backup", \t"freeSpace": 65.9345016479492, \t"totalSpace": 558.877925872803, \t"diskLetter": "Z:"}]\r\n', b'{\t"firewallStatus": "OK"}\r\n']

我只是不明白为什么......

这是一个powershell脚本:

$scriptpath = Split-Path $MyInvocation.MyCommand.Path
Push-Location $scriptpath
#Importing the file where the JSON function are
. ".\util\json.ps1"

   #Get the WMIObject who contain the lastbootuptime and convert it into DateTime
   $os = Get-WmiObject win32_operatingsystem
   $uptime = (Get-Date) - ($os.ConvertToDateTime($os.lastbootuptime))
   #Preparing the object uptimeClean with the object $Uptime to convert it into JSON
   $uptimeClean = @{
    Uptime = '' + $Uptime.Days + ':' + $Uptime.Hours + ':' + $Uptime.Minutes + ':' + $Uptime.Seconds
   }

   Write-Output $uptimeClean | ConvertTo-JSON

有没有办法设置powershell输出编码,或者在python中自动找到编码?

还是其他想法?

0 个答案:

没有答案