Problème avec sous-processus

Fermé
blux Messages postés 26001 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 24 avril 2024 - Modifié par blux le 26/11/2014 à 15:30
blux Messages postés 26001 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 24 avril 2024 - 29 déc. 2014 à 16:13
Bonjour,

je souhaite exécuter des commandes sur un linux via perl mais en conservant un état entre deux commandes. Je m'explique.

J'ai une commande qui s'exécute en ligne comme toute commande standard via bash.
Si je veux la scripter en shell, je suis obligé de la faire précéder de source afin qu'elle ne m'engueule pas (sinon :return: can only `return' from a function or sourced script).
Ca marche bien dans un fichier exécuté via le shell.

Cette commande initialise un environnement, je peux donc, toujours dans un script shell, lancer une autre commande qui s'appuie sur le résultat de la première.

Je cherche à faire la même chose en perl, pour pouvoir récupérer les infos en retour, les analyser et continuer en fonction des résultats.

Je n'arrive pas à lancer ma commande de manière simple avec les backquotes (tenté un /bash/bin source commande) et quand elle s'exécute, elle part dans un shell fils qui se termine dès que la commande est finie.

Y-a-t-il un moyen (simple) ? A part tout écrire en shell ?

Merci d'avance aux bonnes âmes...

A+ blux
 "Les cons, ça ose tout.
C'est même à ça qu'on les reconnait"

1 réponse

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
28 nov. 2014 à 14:47
Salut blux :-)

Je ne suis pas sûr de bien saisir ton problème, mais si ce que tu veux c'est importer les changements de variables d'environnement dans ton environnement d'exécution Perl (dans %ENV), ce module CPAN est conçu pour cela :

Shell::EnvImporter

Outre des scripts ou commandes, il permet même de mettre en entrée des fichiers de configuration utilisés par le shell (par exemple .bashrc).


Dal
0
blux Messages postés 26001 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 24 avril 2024 3 289
Modifié par blux le 28/11/2014 à 17:28
Merci de te pencher sur mon problème ;-)

Je ne suis pas sûr de bien saisir ton problème
C'est normal.

Je t'explique le contexte :
je dispose d'une machine Linux sur laquelle est déployée une appliance nommée vMA, il s'agit d'une appliance destinée à gérer à distance des machines virtuelles VMware
Ces machines virtuelles (nommées VM) sont installées sur des serveurs physiques (nommés ESXi) mais elles déplaçables dynamiquement/automatiquement de l'un à l'autre de ces ESXi en fonction de leur charge (ou d'autres paramètres).
Le tout est géré via une VM sur laquelle est installée une appliance nommée vCenter (qui elle, sait tout à un instant donné de l'architecture en route : quelle VM est en exécution, sur quelle machine physique...

Mon appliance vMA doit donc dialoguer avec soit une machine physique, soit le vCenter.
Il est livré dans cette vMA plein de binaires qui sont destinés à établir le dialogue entre vMA et les ESXi ou vCenter. Notamment, une couche qui permet de saisir des 'credentials' avec user/mot de passe afin que des scripts utilisateurs ne soient pas obligés de les faire figurer en dur dans le code.

Là où on arrive à ce que je souhaite, c'est qu'avant d'aller donner un ordre à un ESXi/vCenter pour lui dire d'effectuer une opération sur une VM, je dois le positionner comme mon 'défaut' pour la session en cours (car je pourrais m'adresser à l'un ou l'autre des ESXi/vCenter). Ce positionnement se fait grâce à une commande livrée (nommée vifptarget). Je peux ensuite passer un script perl qui va s'adresser à la machine 'défaut' pour effectuer son action sur la VM.

Mon problème se situe à deux niveaux :

- la commande de positionnement de la machine 'défaut' n'est pas scriptable en l'état (via un shell, je suis obligé de la préfixer avec source sinon j'ai ma petite erreur, je peux sans doute l'intercepter en retour perl et la traiter comme il se doit). Ce n'est pas à proprement parler un problème mais ça m'ennuie.
- une fois que j'ai lancé cette commande via perl (avec backquote) et que je retourne dans mon perl pour exécuter ma commande d'action sur une VM, je n'ai plus mon 'défaut' positionné puisqu'il s'est déroulé dans un contexte différent (PID fils) et donc je ne peux rien faire

Et quand je pense que ma vMA est destinée à être accédée via SSH depuis un AIX, ça ne me rassure pas ;-)

C'est plus clair ?

J'ai juste pas envie de tout écrire en shell car je trouve perl bien mieux pour ce que j'ai à faire (log des actions, mise en page...)
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
29 nov. 2014 à 01:35
si ce "positionnement" consiste à initialiser certaines variables d'environnement, comme ton premier message le laissait supposer, je pense que Shell::EnvImporter devrait faire l'affaire.

As tu regardé sa doc sur CPAN ?
0
blux Messages postés 26001 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 24 avril 2024 3 289
1 déc. 2014 à 09:25
Oui mais comme perl lance un shell à chaque commande, les variables d'environnement ne sont plus garanties en retour de la commande, non ?
De plus, je ne veux pas les récupérer, je ne sais même pas comment elles sont positionnées par la commande vifptarget.
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 1/12/2014 à 12:51
Je n''utilise pas trop VMWare, mais après quelques recherches Google, d'après ma compréhension VMWare définit vifptarget comme suit :

alias vifptarget="source /opt/vmware/vma/bin/vifptarget"


il semble que cela soit donc un script shell, qui par le biais de "source" est sourcé par le même shell où il est lancé.

dans ces conditions, il y a des chances que cela fonctionne de la même façon que ceci :

$ cat set_env.sh
#!/bin/bash
export MY_VAR=12345
$ cat blux.pl

#!/usr/bin/perl

use strict;
use warnings;

use Shell::EnvImporter;

print "Here, MY_VAR is not yet defined...\n";
print "MY_VAR = " . $ENV{'MY_VAR'} . "\n";

my $sourcer  = Shell::EnvImporter->new(
                   file => "/path/to/sourced/script/set_env.sh",
                 );

print "Now, MY_VAR should be defined...\n";
print "MY_VAR = " . $ENV{'MY_VAR'} . "\n";

$ ./blux.pl 
Here, MY_VAR is not yet defined...
Use of uninitialized value $ENV{"MY_VAR"} in concatenation (.) or string at ./blux.pl line 9.
MY_VAR =
Now, MY_VAR should be defined...
MY_VAR = 12345
$


L'environnement créé par le script sourcé est bien importé dans celui propre au processus Perl, et il dure le temps que durera ce processus.

à la place de
file => "/path/to/sourced/script/set_env.sh"
tu mets
file =>  "/opt/vmware/vma/bin/vifptarget"
dans le constructeur, et cela devrait importer les variables d'environnement.

Selon la doc, ce Module Perl fait cela :

- en créant une sauvegarde de l'environnement,
- en créant un script shell qui source le script à sourcer (ou qui exécute la commande à exécuter)
- en exécutant le script (dans un process disctinct, forcément)
- en parsant le résultat du script pour récupérer les changements effectués à l'environnement
- en important ces changements dans le processus dans lequel Perl fonctionne


Dal
0
blux Messages postés 26001 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 24 avril 2024 3 289
29 déc. 2014 à 16:13
Bon en fait j'ai feinté, car je ne peux pas récupérer l'environnement du sous-processus généré par la commande shell exécutée en perl.

Je suis donc passé par un bout de shell qui appelle le perl, comme ça, perl bénéficie des variables et autres joyeusetés (chargement de librairies...) positionnées par son appelant ;-)

Merci quand même de t'être penché sur ce problème disons, spécifique...
0