Я хочу определить текущее использование ЦП в кучу компьютеров Linux, все из которых доступны через SSH-соединение. На данный момент я что-то сделал с помощью модулей psutil и subprocess, но это могло быть намного проще, если бы я мог получить список из subprocess.check_output.
Поэтому я определил cpu_script.py:
import psutil
print(psutil.cpu_percent(interval=1,percpu=True))
для вызова в моем основном скрипте, который находится в той же папке, с:
import subprocess
import os
import numpy as np
import psutil
usr = "AA"
computer = "BB"
cpu_script = os.path.join(os.getcwd(),"cpu_script.py")
test = subprocess.check_output("ssh -X " + usr + "@" + computer +
"python3 -u - < " + cpu_script,shell=True).strip()
Поскольку выходы cpu_percent обычно входят в список, я бы ожидал, что моя "тестовая" переменная будет списком, но я действительно получаю байт:
input(test)
>> b'[4.0, 5.0, 7.0, 10.9, 18.4, 1.0, 4.0, 3.0]'
input(type(test))
>> <class 'bytes'>
Здесь мне удалось согнуть все, чтобы, наконец, получить массив (с расшифровкой + replace + np.fromstring), но он далек от удовлетворения:
tmp = test.decode("utf-8")
input(tmp)
>> [4.0, 5.0, 7.0, 10.9, 18.4, 1.0, 4.0, 3.0]
input(type(tmp))
>> <class 'str'>
tmp = (tmp.replace('[','')).replace(']','')
result = np.fromstring(tmp, sep=',')
input(result)
>> [ 4. 5. 7. 10.9 18.4 1. 4. 3. ]
input(type(result))
>> <class 'numpy.ndarray'>
Could'nt Я имею сразу переменную subprocess.check_output, которая представляет собой список или массив? Что мне не хватает?
Также, если есть способ избежать определения cpu_script, поэтому, чтобы передать непосредственно команду python в подпроцессе, мне было бы интересно! Я потерпел неудачу на всех моих попытках сделать это пока, сложная часть здесь заключается в том, что есть как ssh connexion, так и консольная команда python3, за которыми следуют команды python.
Спасибо за вашу помощь!
В основе программы python "сериализован" вывод как текст.
check_output
возвращает объект bytes
, который необходимо декодировать, затем "unserialize".
Я предлагаю:
import ast
result = ast.literal_eval(test.decode())
Лучшим способом было бы назвать этот скрипт суб-питона как модуль. В этом случае вам не пришлось бы запускать подпроцесс/сериализовать/несериализовать. Просто импортируйте подмодуль, вызовите функцию и получите реальный list
. Конечно, в случае вызова подпроцесса ssh
вы не можете.
Однако вы могли бы улучшить этот уродливый и check_output
код-инъекцию вызова check_output
требующего shell=True
, передав файл-дескриптор открытого файла python для выполнения, подав вывод на вход check_output
и используя список строк вместо строки как аргумент:
with open(cpu_script,"rb") as f:
test = subprocess.check_output(["ssh","-X",usr + "@" + computer,"python3","-u","-"],stdin=f)
за которым следует код декодирования + оценки.
script_cpu
наfct_cpu()
или даже прямо"psutil.cpu_percent(interval=1,percpu=True)"
в моем вызове подпроцесса, Я получаю сообщение об ошибке:subprocess.CalledProcessError: Command 'ssh -X .... ' returned non-zero exit status 2
subprocess
(ну, есть модульparamiko
, но я сомневаюсь, что он может запускать вызовы python изначально)