在Python中以相同进程执行BASH命令

5 投票
4 回答
11749 浏览
提问于 2025-04-15 22:51

我需要在使用 Python 2.6 导入 ibm_db_dbi 之前,先执行这个命令 . /home/db2v95/sqllib/db2profile

如果在进入 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 个回答

-1

也许你需要的是 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?

0

我不太清楚你在使用什么操作系统和哪个版本的DB2。较新的版本(至少是9.5及以上,9.0或9.1我就不太确定了)是通过把db2clp设置为**$$**来工作的。因为DB2通常是一个LUW(Linux、Unix、Windows),所以在Linux或Unix上也可能能用。不过,在AIX系统上,我需要运行一个配置脚本才能连接到正确的数据库实例。我还没有仔细研究这个脚本具体是干什么的。

10

你在调用一个 '.' 的命令。这个命令的意思是“在当前进程中执行这个 shell 文件”。但是你不能在 Python 进程中执行 shell 文件,因为 Python 不是一个 shell 脚本解释器。

/home/b2v95/sqllib/db2profile 这个文件可能会设置一些 shell 环境变量。如果你用 system() 函数去读取它,那么这些变量只会在执行这个 shell 的环境中改变,而在调用这个 shell 的进程(也就是你的脚本)中是看不到的。

你只能在启动 Python 脚本之前加载这个文件——你可以写一个 shell 包装脚本,先执行 . /home/b2v95/sqllib/db2profile,然后再执行你的 Python 脚本。

另一种方法是查看 db2profile 文件的内容。如果里面只有 NAME=value 这样的行,你可以在你的 Python 脚本中解析这些内容,并用获取到的数据更新 os.environ。如果这个脚本做了更多的事情(比如调用其他东西来获取值),你可以把整个脚本用 Python 重新实现一遍。

更新 一个想法:把这个脚本读入 Python 中,然后用 Popen 将它传给 shell,脚本执行完后再在同一个 shell 中写 env 命令并读取输出。这样你就能获取到在 shell 中定义的所有变量。现在你可以读取这些变量了。

大概是这样的:

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

撰写回答