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 ?
[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.
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).
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
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.