【问题标题】:subprocess module in pythonpython中的子进程模块
【发布时间】:2014-05-22 10:24:19
【问题描述】:

我必须连接到一个 sybase 数据库并使用 python 脚本运行一个简单的选择查询

在我的服务器上,isql 命令只能从 sybase bin 目录运行,因此我必须在触发查询之前 cd 到该目录。

--------------已编辑---------------- -------------

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

#!/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 子进程模块中使用 isql?

【问题讨论】:

  • 使用导入操作系统; os.chdir(path) 改变路径。
  • 从字符串内部删除括号。事实上,您可以完全删除方括号。
  • 那没用,同样的错误
  • 似乎 isql 可能不存在于该文件夹中。检查我的答案更新。

标签: python subprocess


【解决方案1】:

有一个特定的Popen 参数:cwd,如here 所述。使用数组提供您的命令,然后使用 cwd 参数提供必须执行命令的位置:

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

【讨论】:

  • 是的。这里的大多数其他答案都错过了您将命令作为字符串传递而不使用shell=True,这将无法正常工作。当您使用shell=False 时,您必须将您的命令及其参数作为列表传递。
  • 另外,如果您需要一些帮助,将您的命令正确拆分成一个列表,您可以使用shlex.split() 函数:docs.python.org/2/library/shlex.html#shlex.split
  • 就像@dano 提到的那样,您可以像在shell 中一样使用shell=True 选项发出命令(尽管文档说这是不安全的)。其他可以使用专用库的东西,比如python-sybase.sourceforge.net/examples.html
  • @Disturbed_Entity 如果您只使用subprocess.Popen(['./isql'])(没有任何参数)运行您的命令,它会起作用吗?
【解决方案2】:

Popen 只需要一个 args 参数来运行命令。您可以尝试使用 cd 和 isql 命令作为参数调用 shell,但是从 python 更改工作目录可能更简单

对于前一种方法:

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

对于后者:

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

【讨论】:

  • 如何将其作为参数传递? ['isql', '-S server' -U %s -P %s -D %s
【解决方案3】:

试试:

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"

我对子流程不是超级有经验,但这就是我通常在奇怪的场合使用它的方式。希望其他人可以给出更好的答案/解释。

编辑:删除方括号以消除混淆。

【讨论】:

    【解决方案4】:

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

    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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-13
      • 2013-06-25
      • 2014-03-30
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 2015-03-12
      • 2010-11-19
      相关资源
      最近更新 更多