web-dev-qa-db-fra.com

Stocker la sortie filtrée de la commande dans une variable

J'essaie de stocker le résultat d'une commande cmd en tant que variable en python. Pour y parvenir, j'utilise os.system(), mais os.system() exécute simplement le processus, il ne capture pas la sortie. 

import os


PlatformName = os.system("adb Shell getprop | grep -e 'bt.name'")
DeviceName = os.system("adb Shell getprop | grep -e '.product.brand'")
DeviceID = os.system("adb Shell getprop | grep -e 'serialno'")
Version = os.system("adb Shell getprop | grep -e 'version.release'")

print(PlatformName)
print(DeviceName)
print(DeviceID)
print(Version)

Ensuite, j'ai essayé d'utiliser le module subprocess.

import subprocess
import os


PlatformName = subprocess.check_output(["adb Shell getprop | grep -e 'bt.name'"])
DeviceName = subprocess.check_output(["adb Shell getprop | grep -e '.product.brand'"])
DeviceID = subprocess.check_output(["adb Shell getprop | grep -e 'serialno'"])
Version = subprocess.check_output(["adb Shell getprop | grep -e 'version.release'"])

print(PlatformName)
print(DeviceName)
print(DeviceID)
print(Version)

Je reçois l'erreur suivante 

FileNotFoundError: [WinError 2] Le système ne trouve pas le fichier Spécifié.

Comment puis-je stocker la sortie de la commande sous forme de variable?

9
Wojtek T

Les enjeux ici:

  • passer des arguments comme ceci (chaîne dans une liste, avec des espaces) n'est vraiment pas recommandé
  • passer des arguments tels que this nécessite Shell=True pour avoir une petite chance de fonctionner, et Shell=True est connu pour ses problèmes de sécurité (et d'autres problèmes également, tels que la non-portabilité)
  • grep n'est pas standard sur Windows, et le motif est une regex, ce qui signifie que vous devrez probablement vous échapper de . ("bt\.name").
  • quand non trouvé, grep renvoie 1 et ferait échouer check_output.
  • grep retourne une correspondance, et une nouvelle ligne, que vous devez supprimer

Je réécrirais ceci:

PlatformName = subprocess.check_output(["adb Shell getprop | grep -e 'bt.name'"])

comme:

output = subprocess.check_output(["adb","Shell","getprop"])
platform_name = next((line for line in output.decode().splitlines() if "bt.name" in line),"")

La deuxième ligne est une version "native" de grep (sans regex). Il renvoie la première occurrence de "bt.line" dans les lignes en sortie ou une chaîne vide si non trouvé.

Vous n'avez pas besoin de grep ici (ce qui précède n’est pas strictement équivalent, car il donne le premier événement, pas tout les événements, mais cela devrait être acceptable dans votre cas). Et vos clients peuvent ne pas avoir grep installé sur Windows.

9

Hey j'ai le même problème que toi. Le sous-processus peut faire ce que vous voulez même avec le Shell=False. Le truc est la méthode communiquer () .

with subprocess.Popen(cmdCode,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            cwd = workingDir,
                            bufsize=1,
                            universal_newlines = True) as proc:
    #output is stored in proc.stdout
    #errors are stored in proc.stderr

Maintenant, vous avez juste besoin d’une petite fonction pour scanner le proc.stdout avec les informations dont vous avez besoin: PlatformName, etc.

2
Sharku