Python - Enrengistrer une commande dans une variable

Salut,

J’ai un script de gestion d’utilisateur à créer. Connaissant deja un peu le Bash, je souhaite changer et me lancer dans le Python.

Est-il possible de recuperer dans une variable le resultat d’une commande ? En bash par exemple j’utiliserai : cmd=$(grep toto /etc/passwd) et si oui comment ? :017

Merci d’avance,

Bastichou

J’ai reussi à avancer sur le sujet en trouvant cette commande :

cmd=os.popen(cat -d: -f1 /etc/passwd)

Lorsque je lance cette commande depuis la ligne de commande python, elle fonctionne, cependant dans un script, voici le message d’erreur :

cut: write error: Broken pipe

Quelqu’un aurait-il une idée ?

Merci

Salut,

cat ou cut ?

Sinon, ta commande doit être sous forme de chaîne :

[code]>>> import os

res = os.popen(“cut -d: -f1 /etc/passwd”)
res.readlines()
[‘root\n’, ‘daemon\n’, ‘bin\n’, ‘sys\n’, ‘sync\n’, ‘games\n’, ‘man\n’, ‘lp\n’, ‘mail\n’, ‘news\n’, ‘uucp\n’, ‘proxy\n’, ‘www-data\n’, ‘backup\n’, ‘list\n’, ‘irc\n’, ‘gnats\n’, ‘nobody\n’, ‘libuuid\n’, ‘syslog\n’, ‘messagebus\n’, ‘avahi-autoipd\n’, ‘avahi\n’, ‘couchdb\n’, ‘speech-dispatcher\n’, ‘usbmux\n’, ‘haldaemon\n’, ‘kernoops\n’, ‘pulse\n’, ‘rtkit\n’, ‘saned\n’, ‘hplip\n’, ‘gdm\n’, ‘user\n’, ‘terp\n’, ‘postfix\n’][/code]

Cependant, os.Popen est déprécié depuis Python 2.6, il faut privilégier l’utilisation du module subprocess à la place.

Mince j’ai zapé de répondre !
Dans 90 % des cas c’est inutile (cat, cut, grep, sed, awk, head, tail,…).

Pour ton exemple :

[code]#!/usr/bin/python

def cut(char, index, path):
with open(path, ‘r’) as f:
return [ line.split(char, index+1)[index] for line in f.readlines() ]

Attention les index commencent a 0

print cut(’:’, 0, ‘/etc/passwd’)[/code]
C’est plus performant et plus joli.

Merci d’avoir répondu.

Oui s’etais bien un “cut” et non un “cat”…

MisterFreez, je suis débutant en python ^^, et je ne comprends pas tout ce que tu as écrit.

  • Déclaration d’un fonction “cut” avec comme argument les infos nécéssaire (-d, -f et file) : Ok

  • with open(path, 'r') as f: Je suppose que cela permet d’ouvrir le fichier dans la variable “f” ? Que signifie “with” exactement ?

  • La ligne du return… je comprends pas grand choses :s mise à part qu’il lit le fichier ligne par ligne ?

Je vais chercher de mon coté mais si quelqu’un saurait m’expliqué :slightly_smiling:

Bonne soirée !

[quote=“MisterFreez”]Mince j’ai zapé de répondre !
Dans 90 % des cas c’est inutile (cat, cut, grep, sed, awk, head, tail,…).

Pour ton exemple :

[code]#!/usr/bin/python

def cut(char, index, path):
with open(path, ‘r’) as f: # on ouvre le fichier situé à path dans la variable f
return [ line.split(char, index+1)[index] for line in f.readlines() ]
# ici il faut lire de la fin au début
# on prend le fichier f ligne par ligne
# on découpe la ligne en une liste, dont le séparateur est char
# avec index+1, on s’assure de regarder que la première occurence de char, si index=0 comme dans l’exemple
# avec [index], on retourne uniquement l’occurence contenant char

Attention les index commencent a 0

print cut(’:’, 0, ‘/etc/passwd’)[/code]
C’est plus performant et plus joli.[/quote]
En ouvrant le fichier avec with, ça t’évite d’oublier de le refermer puisque tout le reste se fait dans le bloc incrémenté. C’est plus sécurisé.
Je ne suis pas sûr de mes commentaires, donc à confirmer…
Sinon, de façon générale, pour récupérer le résultat d’une commande dans une variable :

C’est fait exprès plus ou moins. Il vaut mieux montrer pleins de choses. Là j’ai cherché à être conçis pour bien montrer que ce n’est pas plus long. Et tu va voir c’est simple.

Exacte

Dans la majorité des langages quand on ouvre un fichier il faut le fermer. En python ça se fait ainsi :

fichier = open('path', 'r')
# ce que tu veux faire
fichier.close()

Mais ces dernières années une nouvelle technique se démocratise, elle consiste à créer un bloque d’instructions dans le quel seras ouvert le fichier et dès que l’on sort de ce bloque (et quelque soit la manière, donc même avec un exit par exemple), le fichier sera refermé. En python, ça se fait avec le mot clef with.

Ici l’intérêt est faible, il sert principalement à être plus concis : nous aurions besoin de 2 lignes supplémentaires pour faire la même chose sans :

def cut(char, index, path): f = open(path, 'r') ret [ line.split(char, index+1)[index] for line in f.readlines() ] f.close() return ret

Note que cela ne marche pas qu’avec les fichiers mais aussi d’autres types de ressources que l’on doit libérer après le traitement.

C’est comme en mathématiques : « On fait un truc pour tout line dans les lignes lues du fichier ». Ça crée une liste avec le résultat de truc pour chaque ligne.

Maintenant le truc :

  • On prend la ligne (line) qu’on découpe sur char (line.split(char)) ça construit un tableau. Pour faire des économie de bouts de chandelles on limite la taille du tableau résultat à index+1 éléments (ainsi la méthode split n’aura pas à parcourir toute la chaîne avant de finir son traitement)* : line.split(char, index+1)
  • On obtiens un tableau, on ne garde que l’élément index.

Voila je sais pas si j’ai était particulièrement claire.

  • je vais détailler avec un exemple, prenons les deux instructions suivantes :

[code]>>> ‘c:o:u:c:o:u’.split(’:’)
[‘c’, ‘o’, ‘u’, ‘c’, ‘o’, ‘u’]

‘c:o:u:c:o:u’.split(’:’, 1)
[‘c’, ‘o:u:c:o:u’][/code]
La seconde fois (en principe) la méthode n’a pas besoin de parcourir l’ensemble de la chaîne “c:o:u:c:o:u” dès qu’elle rencotre le premier ‘:’ elle effectue la découpe et renvoie le résultat. Je dis ça il est tout de même probable qu’il ne fasse pas d’optimisation, je n’en sais rien, ça dépend même peut être de l’interpréteur que tu utilise.

[code]#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

sub cut {
my ($char, $index, $file) = @_;
open FILE, ‘<’, $file or die $!;
my @ret = map { (split /$char/)[$index] } ;
close FILE;
return @ret;
}

Attention les index commencent a 0

say join “\n”, (cut ‘:’, 0, ‘/etc/passwd’);[/code]
J’aime bien la version perl, bien qu’elle soit moins concise (il y a de vrais morceaux de fun dedans).

Vous avez tous les deux été très claire ! Merci beaucoup !

J’ai juste une petite question :
- Faut importer des modules pour utiliser split ?

Je pense qu’avant de me lancer dans le perl je vais approfondir le python :slightly_smiling: , mais je doute que ce soit des langages très différents ?

Bonne soirée à tous

Vous avez tous les deux été très claire ! Merci beaucoup !

J’ai juste une petite question :
- Faut importer des modules pour utiliser split ?

Je pense qu’avant de me lancer dans le perl je vais approfondir le python :slightly_smiling: , mais je doute que ce soit des langages très différents ?

Bonne soirée à tous

Non, pas besoin d’importer quoi que ce soit pour utiliser split.

Entre perl et python, c’est proche dans le sens où ce sont deux langages de script objet et impératif à la fois. Mais leur philosophie est totalement différente. En python il existe une et une seule manièure de faire une chose et il est batterie included (beaucoup de bibliothèques font parties du package standard) en perl c’est exactement l’inverse.

Au final python est très simple et impose des règles là où perl n’impose rien, mais il est plus compliqué et semble plus vieux.

la méthode split fait partie des objets str (chaine de caractère) qui font bien partie de la bibliothèqe standard de python. Donc pas d’importation nécéssaire.
Un truc essentiel pour s’en sortir en python :
docs.python.org/library/ pour python 2
docs.python.org/py3k/library/ pour python 3

D’accord, je m’interesse de plus en plus à ces languages. Ils sont beaucoup utilisés là ou je travail !

Y-a-t-il une grande différence en Python2.x et Python3 ? Dois-je apprendre en priorité plutot l’un que l’autre ?

La réponse officielle est ici : wiki.python.org/moin/Python2orPython3

Il vaut mieux utiliser python 3 : plus de fonctionnalité, plus rapide… etc.
Cependant, toutes les librairies qui existaient pour python 2 ne sont pas encore portée. Donc tu peux utiliser le script 2to3 proposé sur le site de python ci-dessus, ou bien écrire tes programmes de sorte qu’ils puissent fonctionner à la fois avec python2 et 3. C’est ce que je fais, et mis à part input() et raw_input() qui n’est pas présente dans 3 (plus de sécurité), je m’en sors pour l’instant.
Rest eà voir si cela reste vrai plus une utilisation plus poussée de python.