Выполните команду BASH в Python - в том же процессе - PullRequest
4 голосов
/ 18 мая 2010

Мне нужно выполнить команду . /home/db2v95/sqllib/db2profile, прежде чем я смогу import ibm_db_dbi в Python 2.6.

Выполнение перед входом в Python работает:

baldurb@gigur:~$ . /home/db2v95/sqllib/db2profile
baldurb@gigur:~$ 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
>>> 

, но выполнение его в Python с использованием os.system(". /home/db2v95/sqllib/db2profile") или subprocess.Popen([". /home/db2v95/sqllib/db2profile"]) приводит к ошибке. Что я делаю не так?

Редактировать: это ошибка, которую я получаю:

> 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

Ответы [ 4 ]

10 голосов
/ 18 мая 2010

Вы звоните "." командная оболочка. Эта команда означает «выполнить этот файл оболочки в текущем процессе». Вы не можете выполнить файл оболочки в процессе Python, так как Python не является интерпретатором сценария оболочки.

/home/b2v95/sqllib/db2profile, вероятно, устанавливает некоторые переменные среды оболочки. Если вы прочитаете ее, используя функцию system(), переменные будут изменены только в исполняемой оболочке и не будут видны в процессе, вызывающем эту оболочку (ваш скрипт).

Вы можете загрузить этот файл только перед запуском сценария Python - вы можете создать сценарий оболочки-оболочки, который будет выполнять . /home/b2v95/sqllib/db2profile и выполнить сценарий Python.

Другой способ - увидеть, что содержит db2profile. Если это всего лишь NAME=value строк, вы можете проанализировать его в своем скрипте Python и обновить os.environ полученными данными. Если скрипт делает что-то большее (например, вызывает что-то еще для получения значений), вы можете переопределить весь скрипт в Python.

Обновление Идея: прочитать скрипт в python, передать его (используя Popen) в оболочку, после того, как скрипт напишет команду env в той же оболочке и прочитать вывод. Таким образом, вы получите все переменные, определенные в оболочке. Теперь вы можете читать переменные.

Примерно так:

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 голосов
/ 27 мая 2010

Не уверен, с какой ОС вы работаете и какую версию DB2 вы используете. Более новые версии (по крайней мере, 9.5 и выше, не уверен насчет 9.0 или 9.1) работают, устанавливая db2clp в **$$**. Поскольку DB2 обычно является LUW, она может работать и под linux / unix. Однако в AIX мне нужно запустить скрипт профиля, чтобы подключиться к нужному экземпляру БД. Не слишком много проверялось, что делает этот скрипт.

0 голосов
/ 18 мая 2010

вам нужно сделать:

subprocess.Popen(['.', '/home/db2v95/sqllib/db2profile'], shell=True)
0 голосов
/ 18 мая 2010

Может быть os.popen - это то, что вы ищете (еще лучше, один из вариантов popen[2-4])? Пример:

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

Редактировать: Я вижу, что ваша ошибка говорит No such file or directory. Попробуйте запустить его без точки, вот так:

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

Если это не сработает, это может быть связано с вашей средой. Может быть, вы используете Python в тюрьме / chroot?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...