2010-05-18 5 views
3

je dois exécuter la commande . /home/db2v95/sqllib/db2profile avant que je puisse import ibm_db_dbi en Python 2.6.Exécuter une commande BASH dans Python-- dans le même processus

il exécution avant d'entrer Python fonctionne:

[email protected]:~$ . /home/db2v95/sqllib/db2profile 
[email protected]:~$ python 
Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15) 
[GCC 4.4.1] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import ibm_db_dbi 
>>> 

mais l'exécuter en Python en utilisant os.system(". /home/db2v95/sqllib/db2profile") ou subprocess.Popen([". /home/db2v95/sqllib/db2profile"]) provoque une erreur. Qu'est-ce que je fais mal?

Edit: ceci est l'erreur que je reçois:

> Traceback (most recent call last): 
> File "<file>.py", line 8, in 
> <module> 
>  subprocess.Popen([". /home/db2v95/sqllib/db2profile"]) 
> File 
> "/usr/lib/python2.6/subprocess.py", 
> line 621, in __init__ 
>  errread, errwrite) File "/usr/lib/python2.6/subprocess.py", 
> line 1126, in _execute_child 
>  raise child_exception OSError: [Errno 2] No such file or directory 
+0

Total des estimations, mais il semble que le script définit certaines choses dans l'environnement, ce qui ne fonctionnera probablement pas en exécutant un sous-processus. – abyx

+0

@abyx: mais c'est sans rapport avec le problème donné, même s'il est vrai – SilentGhost

Répondre

-1

Peut-être os.popen est ce que vous cherchez (mieux encore, l'une des variantes popen[2-4])? Exemple:

import os 
p = os.popen(". /home/b2v95/sqllib/db2profile") 
p.close() # this will wait for the command to finish 
import ibm_db_dbi 

Edit: Je vois que votre erreur indique No such file or directory. Essayez de l'exécuter sans le point, comme ceci:

os.popen("/home/b2v95/sqllib/db2profile") 

Si cela ne fonctionne pas, cela peut avoir un rapport avec votre environnement. Peut-être que vous exécutez Python emprisonné/chrootisé?

+1

'os.popen' est dépréciée – SilentGhost

+1

Oh, zut. Je n'ai pas vu le grand avertissement rouge. Désolé pour ça. – Felix

+0

Non seulement déprécié - jamais destiné à être utilisé de cette façon (pour ouvrir le tuyau et ignorer la sortie). Si vous voulez simplement exécuter une commande shell sans communiquer avec, utilisez 'os.system()' ou 'subprocess.call()', pas 'os.popen()'. –

0

vous devez faire:

subprocess.Popen(['.', '/home/db2v95/sqllib/db2profile'], shell=True) 
+0

Cela peut "fonctionner" (ne pas lever d'exception), mais très probablement ne fera pas ce qui est attendu. Comme le fichier est «source», il définit probablement certaines variables d'environnement. Ces variables ne seront définies que dans le shell lancé par Popen et non visible dans l'appel de script Python. –

+0

Il en résulte: retraçage (le plus récent appel dernier): Fichier "gagnagrunnur.py", ligne 14, à importation ibm_db_dbi Fichier « /usr/local/lib/python2.6/dist-packages/ibm_db_dbi .py ", ligne 26, dans import ibm_db ImportError: libdb2.so.1: impossible d'ouvrir le fichier objet partagé: aucun fichier ou répertoire de ce type Je tiens à souligner que cela a fonctionné en utilisant la ligne de commande. –

+0

@baldur: attendez-vous que le processus se termine? – SilentGhost

10

Vous appelez un '' commande shell. Cette commande signifie 'exécuter ce fichier shell dans le processus en cours'. Vous ne pouvez pas exécuter le fichier shell dans le processus Python car Python n'est pas un interpréteur de script shell.

Le /home/b2v95/sqllib/db2profile définit probablement certaines variables d'environnement shell. Si vous lisez à l'aide de la fonction system(), les variables seront changés dans la coquille exécutée et ne seront pas visibles dans le processus d'appel que shell (script).

Vous pouvez seulement charger ce fichier avant de commencer votre script python - vous pouvez créer un script shell wrapper qui fera . /home/b2v95/sqllib/db2profile et exécuter votre script python.

Autre moyen serait de voir ce que le db2profile contient. Si ce ne sont que NAME=value lignes, vous pouvez l'analyser dans votre script python et mettre à jour os.environ avec les données obtenues. Si le script fait quelque chose de plus (comme appeler autre chose pour obtenir les valeurs), vous pouvez réimplémenter tout le script en Python.

Mise à jour Une idée: lire le script en python, la pipe (à l'aide Popen) à la coquille, après le script écrire commande env à la même coquille et lire la sortie. De cette façon, vous obtiendrez toutes les variables définies dans le shell. Maintenant, vous pouvez lire les variables.

Quelque chose comme ceci:

shell = subprocess.Popen(["sh"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 
script = open("/home/db2v95/sqllib/db2profile", "r").read() 
shell.stdin.write(script + "\n") 
shell.stdin.write("env\n") 
shell.stdin.close() 
for line in shell.stdout: 
    name, value = line.strip().split("=", 1) 
    os.environ[name] = value 
+0

Ah, bon point-- db2profile définit en effet des variables d'environnement shell. Malheureusement je ne peux pas appeler le script python en utilisant un wrapper shell (en raison de la nature du projet), le profil db2 est long et inclut des fonctions modérément compliquées et (vous l'aurez deviné) des variables d'environnement. Comment est-ce que je pourrais exécuter le fichier entier en Python? –

+0

I.e. Est-il possible d'exécuter un script BASH avec beaucoup d'affectations, de variables d'environnement et de fonctions dans Python? Ou devrais-je réécrire tout le code en Python? –

+0

J'ai eu une idée de comment cela pourrait être fait: voir la mise à jour de mon message. –

0

Je ne sais pas quel système d'exploitation sur lequel vous travaillez et quelle version DB2 que vous utilisez. Les versions plus récentes (au moins 9,5 et au-dessus, ne suis pas sûr 9.0 ou 9.1) le travail en mettant à db2clp **$$**. Comme le DB2 est généralement un LUW, il peut aussi fonctionner sous linux/unix.Cependant, sous AIX, je dois exécuter le script de profil pour me connecter à l'instance de base de données appropriée. Je n'ai pas trop vérifié ce que fait ce script.

Questions connexes