# Python - Enrengistrer une commande dans une variable

**URL:** <https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341>\
**Category:** Programmation\
**Created:** [Février 21, 2016, 3:59 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341 "2016-02-21T03:59:09Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bastichou](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/a9adbd/32.png) [@Bastichou](https://www.debian-fr.org/u/Bastichou)\
**Post date:** [Février 21, 2016, 3:59 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/1 "2016-02-21T03:59:09Z")

</div>

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](https://www.debian-fr.org/uploads/default/original/1X/7bbea83f89515ab7c7a738dddb86c4d4f140bd13.gif "reflechit")

Merci d’avance,

Bastichou

---

<div class="post-metadata">

**Author:** ![Bastichou](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/a9adbd/32.png) [@Bastichou](https://www.debian-fr.org/u/Bastichou)\
**Post date:** [Février 21, 2016, 3:59 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/2 "2016-02-21T03:59:54Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Keldath](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/k/f17d59/32.png) [@Keldath](https://www.debian-fr.org/u/Keldath)\
**Post date:** [Février 21, 2016, 3:59 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/3 "2016-02-21T03:59:54Z")

</div>

Salut,

cat ou cut ?

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

[code]\>\>\> import os

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

Cependant, os.Popen est déprécié depuis Python 2.6, il faut privilégier l’utilisation du module [subprocess](http://docs.python.org/library/subprocess.html) à la place.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 3:59 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/4 "2016-02-21T03:59:55Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Bastichou](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/a9adbd/32.png) [@Bastichou](https://www.debian-fr.org/u/Bastichou)\
**Post date:** [Février 21, 2016, 3:59 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/5 "2016-02-21T03:59:57Z")

</div>

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é 🙂

Bonne soirée !

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 3:59 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/6 "2016-02-21T03:59:57Z")

</div>

[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 :

```auto

```

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 3:59 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/7 "2016-02-21T03:59:57Z")

</div>

> [@Bastichou](#):
>
> MisterFreez, je suis débutant en python ^^, et je ne comprends pas tout ce que tu as écrit.

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.

> [@Bastichou](#):
>
> - Déclaration d’un fonction «&nbsp;cut&nbsp;» avec comme argument les infos nécéssaire (-d, -f et file) : Ok

Exacte

> [@Bastichou](#):
>
> - `with open(path, 'r') as f: ` Je suppose que cela permet d’ouvrir le fichier dans la variable «&nbsp;f&nbsp;» ? Que signifie «&nbsp;with&nbsp;» exactement ?

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

```auto
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.

> [@Bastichou](#):
>
> - La ligne du return.. je comprends pas grand choses :s mise à part qu’il lit le fichier ligne par ligne ?

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]\>\>\> ‹&nbsp;c:o:u:c:o:u&nbsp;›.split(‹&nbsp;:&nbsp;›)  
[‹&nbsp;c&nbsp;›, ‹&nbsp;o&nbsp;›, ‹&nbsp;u&nbsp;›, ‹&nbsp;c&nbsp;›, ‹&nbsp;o&nbsp;›, ‹&nbsp;u&nbsp;›]

> > > ‹&nbsp;c:o:u:c:o:u&nbsp;›.split(‹&nbsp;:&nbsp;›, 1)  
> > > [‹&nbsp;c&nbsp;›, ‹&nbsp;o:u:c:o:u&nbsp;›][/code]  
> > > La seconde fois (en principe) la méthode n’a pas besoin de parcourir l’ensemble de la chaîne «&nbsp;c:o:u:c:o:u&nbsp;» dès qu’elle rencotre le premier ‹&nbsp;:&nbsp;› 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.

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 3:59 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/8 "2016-02-21T03:59:58Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Bastichou](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/a9adbd/32.png) [@Bastichou](https://www.debian-fr.org/u/Bastichou)\
**Post date:** [Février 21, 2016, 4:00 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/9 "2016-02-21T04:00:14Z")

</div>

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 🙂 , mais je doute que ce soit des langages très différents ?

Bonne soirée à tous

---

<div class="post-metadata">

**Author:** ![Bastichou](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/a9adbd/32.png) [@Bastichou](https://www.debian-fr.org/u/Bastichou)\
**Post date:** [Février 21, 2016, 4:00 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/10 "2016-02-21T04:00:14Z")

</div>

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 🙂 , mais je doute que ce soit des langages très différents ?

Bonne soirée à tous

---

<div class="post-metadata">

**Author:** ![MisterFreez](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/m/bb73d2/32.png) [@MisterFreez](https://www.debian-fr.org/u/MisterFreez)\
**Post date:** [Février 21, 2016, 4:00 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/11 "2016-02-21T04:00:17Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 4:00 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/12 "2016-02-21T04:00:27Z")

</div>

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/](http://docs.python.org/library/) pour python 2  
[docs.python.org/py3k/library/](http://docs.python.org/py3k/library/) pour python 3

---

<div class="post-metadata">

**Author:** ![Bastichou](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/b/a9adbd/32.png) [@Bastichou](https://www.debian-fr.org/u/Bastichou)\
**Post date:** [Février 21, 2016, 4:00 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/13 "2016-02-21T04:00:29Z")

</div>

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 ?

---

<div class="post-metadata">

**Author:** ![thuban](https://www.debian-fr.org/user_avatar/www.debian-fr.org/thuban/32/4177_2.png) [@thuban](https://www.debian-fr.org/u/thuban)\
**Post date:** [Février 21, 2016, 4:00 UTC](https://www.debian-fr.org/t/python-enrengistrer-une-commande-dans-une-variable/35341/14 "2016-02-21T04:00:31Z")

</div>

La réponse officielle est ici : [wiki.python.org/moin/Python2orPython3](http://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.
