web-dev-qa-db-fra.com

L'appel de ligne de commande Linux ne renvoie pas ce qu'il devrait avoir de os.system?

Je dois faire quelques appels en ligne de commande vers Linux et obtenir le retour, mais le faire comme ci-dessous ne fait que renvoyer 0 alors qu'il devrait renvoyer une valeur temporelle, comme 00:08:19, je teste exactement le même appel en ligne de commande normale retourne la valeur de temps 00:08:19 donc je suis confus quant à ce que je fais mal, car je pensais que c'était comment le faire en python.

import os
retvalue = os.system("ps -p 2993 -o time --no-headers")
print retvalue
56
Rick

Ce qui est renvoyé est la valeur de retour de l'exécution de cette commande. Ce que vous voyez lors de l’exécution directe est le résultat de la commande dans stdout. Que 0 soit retourné signifie qu'il n'y a pas eu d'erreur d'exécution.

Utilisez popen, etc. pour capturer la sortie.

Quelque chose le long de cette ligne:

import subprocess as sub
p = sub.Popen(['your command', 'arg1', 'arg2', ...],stdout=sub.PIPE,stderr=sub.PIPE)
output, errors = p.communicate()
print output

ou 

import os
p = os.popen('command',"r")
while 1:
    line = p.readline()
    if not line: break
    print line

ON SO: Popen et python

98
pyfunc

Si le résultat du processus ne vous intéresse que, il est plus simple d'utiliser le sous-processus ' check_output function:


output = subprocess.check_output(["command", "arg1", "arg2"]);

La sortie conserve ensuite la sortie du programme sur stdout. Consultez le lien ci-dessus pour plus d'informations.

25
JoshD

Le moyen le plus simple est comme ça:

import os
retvalue = os.popen("ps -p 2993 -o time --no-headers").readlines()
print retvalue

Ce sera retourné sous forme de liste

10
IonicBurger

Votre code retourne 0 si l'exécution des commandes passées est réussie et non nulle si elle échoue. Le programme suivant fonctionne sur python2.7, vérifié 3 et les versions ci-dessus. Essayez ce code.

>>> import commands
>>> ret = commands.getoutput("ps -p 2993 -o time --no-headers")
>>> print ret
8
vikkyhacks

Je ne peux pas ajouter de commentaire à IonicBurger parce que je n’ai pas "50 ans de réputation", donc Je vais ajouter une nouvelle entrée. Mes excuses. (os.popen ()) est ce qu'il y a de mieux pour les commandes multiples/compliquées (à mon avis) et pour obtenir la valeur de retour en plus de stdout comme les commandes multiples plus compliquées suivantes:

import os
out = [ i.strip() for i in os.popen(r"ls *.py | grep -i '.*file' 2>/dev/null; echo $? ").readlines()]
print "     stdout: ", out[:-1]
print "returnValue: ", out[-1]

Ceci listera tous les fichiers python qui ont le mot Word 'fichier' n'importe où dans leur nom. Le [...] est une liste de compréhension permettant de supprimer (supprimer) le caractère de nouvelle ligne de chaque entrée. La echo $? _ Est une commande Shell indiquant le statut de retour de la dernière commande exécutée, à savoir la commande grep et le dernier élément de la liste de cet exemple. le 2>/dev/null dit d'imprimer le stderr de la commande grep sur / dev/null afin qu'il n'apparaisse pas dans le résultat. La 'r' avant la 'ls' est d'utiliser la chaîne brute afin que le shell n'interprète pas les métacaractères comme '*' correctement. Cela fonctionne en python 2.7. Voici l'exemple de sortie:

      stdout:  ['fileFilter.py', 'fileProcess.py', 'file_access..py', 'myfile.py']
 returnValue:  0
2
Joe

Oui, c'est contre-intuitif et cela ne semble pas très pythonique, mais cela ne fait en réalité que ressembler à la conception de l'API unix, où ces calld sont des fonctions C POSIX. Vérifier man 3 popen && man 3 system

Un fragment de code un peu plus pratique pour remplacer le système os.system que j’utilise: 

from subprocess import (PIPE, Popen)


def invoke(command):
    '''
    Invoke command as a new system process and return its output.
    '''
    return Popen(command, stdout=PIPE, Shell=True).stdout.read()


result = invoke('echo Hi, bash!')
# Result contains standard output (as you expected it in the first place).
2
Yauhen Yakimovich

Pour répondre à vos besoins, la fonction Popen du module de sous-processus python est la solution. Par exemple,

import subprocess
..
process = subprocess.Popen("ps -p 2993 -o time --no-headers", stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
print stdout
1
Asif Hasnain

Ceci est un ancien fil de discussion, mais en utilisant uniquement os.system, la procédure suivante permet d'accéder aux données renvoyées par l'appel ps. Remarque: il utilise un tuyau pour écrire les données dans un fichier sur le disque. Et OP n'a pas spécifiquement demandé de solution à l'aide de os.system

>>> os.system("ps > ~/Documents/ps.txt")
0    #system call is processed.
>>> os.system("cat ~/Documents/ps.txt")
  PID TTY          TIME CMD
 9927 pts/0    00:00:00 bash
10063 pts/0    00:00:00 python
12654 pts/0    00:00:00 sh
12655 pts/0    00:00:00 ps
0

en conséquence,

>>> os.system("ps -p 10063 -o time --no-headers > ~/Documents/ps.txt")
0
>>> os.system("cat ~/Documents/ps.txt")
00:00:00
0

Aucune idée pourquoi ils retournent tous des zéros.

1
Coriolis Force

okey je crois que le moyen le plus rapide serait

import os
print(os.popen('command').readline())
x = _
print(x)
0
George