Python中的subprocess模块

0 投票
4 回答
771 浏览
提问于 2025-04-18 07:17

我需要用Python脚本连接到一个Sybase数据库,并运行一个简单的查询。

在我的服务器上,isql命令只能在Sybase的bin目录下运行,所以我必须先切换到那个目录,然后才能执行查询。

---------------------------编辑-----------------------------

到目前为止,我已经能够做到这一点:

#!/usr/bin/python
  import subprocess
  path = "path/to/sybase/bin"
  os.chdir(path)
  arguments = ['./isql',"-S server_name", "-U user", "-P password", "-D database","""<<EOF
  SELECT * FROM sometable
  go
  EOF"""]
  ps = subprocess.Popen(arguments)
  out = ps.communicate()
  print out

但是出现的错误我完全看不懂 :(

Traceback (most recent call last):
File "./test_db.py", line 8, in ?
ps = subprocess.Popen(arguments)
File "/usr/lib64/python2.4/subprocess.py", line 542, in __init__
errread, errwrite)
File "/usr/lib64/python2.4/subprocess.py", line 975, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

我可以在我的Unix终端中使用isql命令在Python脚本之外完成这个操作。

我该如何在Python的subprocess模块中使用isql呢?

4 个回答

0

试试这个:

import os
import subprocess

os.chdir('/path/to/sybase/bin')

if os.path.exists('isql') or os.path.exists(os.path.join('/path/to/sybase/bin', 'isql')):
    ps = subprocess.Popen('isql -S %s -U %s -P %s -D %s <<EOF SELECT * FROM sometable EOF' % (server,user,passwd,database), stdout=subprocess.PIPE, shell=True)
    out, err = ps.communicate()
else:
    print "isql does not exists in this folder"

我对子进程不是特别熟悉,但这是我偶尔使用它的方式。希望其他人能给出更好的答案或解释。

编辑:去掉了方括号,以免造成混淆。

0

Popen 只接受一个参数,也就是要运行的命令。你可以尝试用一个 shell 来同时执行 cd 和 isql 这两个命令,但从 Python 中改变工作目录可能会更简单一些。

对于前一种方法:

subprocess.Popen('/bin/sh -c "cd /path/to/... && isql -arg1..'...)

对于后一种方法:

os.chdir('/path/to...')
subprocess.Popen('isql -arg1..'...)
1

这里有一个特别的 Popen 参数:cwd,在这里提到过。你可以用一个数组来提供你的命令,然后用 cwd 参数指定命令要在哪个地方执行:

subprocess.Popen(['ls', '-l'], cwd="/path/to/folder")
0

我知道这已经过了很久,但我只是想把这个问题结束掉。

from subprocess import Popen, PIPE
from textwrap import dedent

isql = Popen(['./isql', '-I', '/app/sybase/...',
              '-S', mdbserver,
              '-U', muserid,
              '-P', password, ...,
              '-w', '99999'], stdin=PIPE, stdout=PIPE, cwd=sybase_path)
output = isql.communicate(dedent("""\
    SET NOCOUNT ON
    {}
    go
""".format(User_Query)))[0]

撰写回答