Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 24/01/2015, à 18:57

Laërte

Équivalents bash <-> python

Bonjour,

je cherche désespérément des modules python qui permettrait de faire la même chose que les programmes find et df en bash...

Si jamais cela n'existe pas, peut-on considérer que la commande :

subprocess.call(shlex.split("bash -c 'df file > retour'"))

avec une lecture ultérieure du fichier retour est une manière acceptable de coder (à part que c'est pas du tout portable comme code, mais le contexte fait que ça n'a aucun intérêt de l'être.) ?

Pour ceux qui ne savent pas la commande shlex.split découpe une chaîne de caractère en paramètres (à passer en ligne de commande), donc en respectant le regroupement à l'aide de guillemets (c'est un module de base).

Voilà !

Merci pour votre aide ! big_smile

Hors ligne

#2 Le 25/01/2015, à 23:45

tiramiseb

Re : Équivalents bash <-> python

Salut,

Ce que tu proposes de faire, c'est quand même vachement crado smile

Tu lances python pour lire un script qui exécuté un sous-processus pour lancer bach pour exécuter la commande df pour mettre son retour dans un fichier pour lire ce fichier ensuite... wow ! Par ailleurs, shlex.split est inutile s'il s'agit juste de séparer des arguments que l'on connaît : autant faire la séparation soi-même directement. shlex.split est utile quand on récupère les arguments par ailleurs.

Pour faire bref : non, ce n'est pas une manière acceptable de coder.


Si on garde l'idée d'exécuter la commande "df", alors je propose plutôt la chose suivante :

df = subprocess.check_output('df')

... là, la variable nommée df contient ce que contiendrait ton fichier "retour".

Ensuite, si tu tiens vraiment à exécuter une commande externe de cette manière, il faut s'arranger pour que son retour soit facilement exploitable par un logiciel. Pour df, il faut utiliser l'argument "-P", ce qui donnerait :

df = subprocess.check_output(['df', '-P'])

Bien sûr, si tu veux utiliser df avec un argument du type nom de fichier, ça donnerait quelque chose comme ça :

df = subprocess.check_output(['df', '-P', 'file'])

Mais ça ne serait pas du tout pythonesque d'appeler une commande externe comme ça.
Il existe la fonction os.statvfs :
https://docs.python.org/2/library/os.html#os.statvfs

Ce qui donnerait :

df = os.statvfs('file')

... bien sûr, à toi ensuite d'exploiter ces données comme tu le veux.

----

Pour un "équivalent" de find, tu as plein de possibilités : "os.listdir", "glob"... ça dépend de ce que tu veux faire avec ça.

Hors ligne

#3 Le 26/01/2015, à 11:42

Laërte

Re : Équivalents bash <-> python

L'idée de df c'était de récupérer le point de montage de la partition sur laquelle est présent le fichier. Je ne peux pas faire ça avec os.statvfs et aucun module ne permet de gérer les points de montages d'une partition en python. Ou en tout cas j'ai pas trouvé, ce qui est pourquoi je demande...

Quant à find, je veux obtenir un résultat équivalent à une recherche du genre :

find /  -path */grub/grub.cfg

.
Sauf que avec glob '*' ne match pas '/' donc on ne peut pas faire de recherche récursive. J'ai bien essayé mais ça me donne une fonction comme ça :

def search(dir, pattern, rec=1):
    """Fonction de recherche de répertoire selon un «pattern».
    <rec> indique le niveau de récursivité.
    Renvoie une liste contenant les chemins correspondant au pattern."""
    dir = path.Path(dir)
    result = list()
    for i in range(rec):
        result += dir.glob('*/' * i + pattern)
    return result

J'utilise le module path.py installé via pip.
Le problème c'est qu'une recherche avec cette fonction me renvoie des entrées contenues dans le dossier /proc qui correspond aux tâches du noyau... >< À moins de faire un filtre sur tous les chemins commençant par '/proc' je vois pas...

Peut-être qu'il faudrait poser la question sur un forum python ? ^^ Comme je suis habitué à celui-ci j'y reste mais j'aurais probablement plus de réponses sur un forum dédié.

Hors ligne

#4 Le 26/01/2015, à 11:54

tiramiseb

Re : Équivalents bash <-> python

L'idée de df c'était de récupérer le point de montage de la partition sur laquelle est présent le fichier

Alors demande comment récupérer le point de montage de la partition sur laquelle est présent un fichier, ne demande pas comment faire l'équivalent de df smile

S'il n'y a pas de module fait pour ça, je proposerais de lire le contenu de /etc/mtab, d'en extraire la liste des points de montages et de comparer ça avec le chemin complet du fichier en question...

Pour le "find", à ta place je le ferais "à l'ancienne" en parcourant répertoire par répertoire, je ne suis pas très fort sur cet aspect-là.
Mais le besoin sous-jascent est-il vraiment de chercher un tel fichier sur tout le filesystem ?

N'y a-t-il pas une possibilité d'améliorer l'expression du besoin à la base ?

Hors ligne

#5 Le 26/01/2015, à 12:31

Laërte

Re : Équivalents bash <-> python

Tu as raison, on va reprendre du début.

L'idée c'est de modifier grub de telle manière qu'on puisse booter sur une iso sans avoir besoin de la "graver" sur CD/DVD/USB. Ça passe par la modification des fichiers de conf contenues dans /boot/grub/.

Le programme en ligne de commande fonctionne bien. L'idée c'est maintenant d'ajouter une interface graphique pour le rendre accessible aux débutants qui ont peur du terminal. Mais ça inclut d'automatiser certaines choses qui ne l'étaient pas forcément avant.

Pour df, j'ai fait comme je l'ai dit plus haut mais comme ça me paraissait crade, j'ai préféré demander voire s'il n'y avait pas une autre solution.

Pour find : normalement mon programme prend comme dossier grub /boot/grub. Mais il propose l'option à l'utilisateur de choisir un autre dossier (j'ai installé grub sur ma clef usb par exemple). Avec une interface graphique, l'idée est de détecter tous ces dossiers grâce au pattern */grub/grub.cfg et d'en proposer une liste à l'utilisateur dans laquelle il pourra faire son choix.

Le besoin est donc plus ou moins de chercher un tel fichier sur tout le filesystem, puisqu'on ne peut pas prévoir où un utilisateur tordu a installé grub... (on peut se douter que ça suit toujours la même logique, mais comme on n'a pas le point de montage des périphériques...)

Si tu as une autre proposition, je suis preneur.

Hors ligne

#6 Le 26/01/2015, à 12:41

tiramiseb

Re : Équivalents bash <-> python

Pour df, j'ai fait comme je l'ai dit plus haut mais comme ça me paraissait crade

Oui, c'est crade. Surtout passer par un fichier intermédiaire, c'est hyper crade.

Au mieux, fais comme je l'ai proposé avec le chemin du fichier et /etc/mtab.
Au pire, exécute df avec subprocess.check_output.

Le besoin est donc plus ou moins de chercher un tel fichier sur tout le filesystem, puisqu'on ne peut pas prévoir où un utilisateur tordu a installé grub...

Dans la plus pure tradition du "release early, release often", je te propose de commencer par proposer à l'utilisateur de parcourir par lui-même les filesystems pour trouver son répertoire.
Ensuite, tu peux sortir une nouvelle version qui appelle "find" avec subprocess.check_output (menfin ça, tu peux le faire dans la 1re version aussi).
Et après, tu auras tout le temps de trouver un joli algo tout en python pour le faire proprement.

N'oublie pas, également, qu'il vaut éviter les lenteurs. Chercher un fichier dans toute l'arborescence, ça peut être très très long. Je pense que ça doit alors faire l'objet d'un bouton spécifique, avec lequel l'utilisateur serait prévenu que ça prend du temps.

Concernant le filtrage de /proc, il faut aussi être vigilant : l'utilisateur peut être tordu au point d'avoir monté son filesystem sous /proc/...

Vouloir intégrer plein de fonctionnalités dès la 1re version, c'est le meilleur moyen pour ne jamais sortir un logiciel smile

Hors ligne

#7 Le 26/01/2015, à 13:11

Laërte

Re : Équivalents bash <-> python

Pour la première version je m'en fais pas, elle est déjà sortie. Juste en ligne de commande, pas de GUI, ça me permet de tester le fonctionnement interne avant de l'intégrer ailleurs.

Je vais d'abord passer par subprocess.check_output je pense le temps de faire une fonction qui puisse analyser /etc/mtab.
Après permettre à l'utilisateur de choisir son rep, j'y ai pensé en ligne de commande, je me demande pourquoi j'y ai pas pensé avec une GUI... Le problème c'est que je ne sais pas comment faire pour ouvrir une fenêtre de sélection de fichier avec tkinter (ce sera mon module pour les premières interfaces, je pense passer à pyside quand j'aurais compris comment ça marche).

Merci beaucoup pour tes réponses ! big_smile

Hors ligne

#8 Le 26/01/2015, à 14:20

tiramiseb

Re : Équivalents bash <-> python

concernant tkinter je ne peux pas t'aider, je n'ai jamais utilisé.

Hors ligne