【问题标题】:django wsgi + Popen + svn checkoutdjango wsgi + Popen + svn 结帐
【发布时间】:2012-07-21 07:43:14
【问题描述】:

出于某种原因,我需要从 django 视图中检出源代码文件夹,为此我使用了“Popen”。

一切正常,在使用 django runserver 时完美运行

但是,在我将代码部署到 apache2 + wsgi 之后,Popen 无法正常工作。它总是在命令实际完成之前返回。它也不会抛出错误,它只是抛出不完整的输出,我检查了签出的文件夹,它们也不完整。

整个 svn check out 过程大约需要 5-6 秒,标准输出相当大(大约 3000 个字符)。

我知道有一个 pysvn 库,但是在过时的 ubuntu 服务器上安装它似乎很困难。

基本上这是我现在唯一卡住的事情。

我用来调用结帐的代码如下:

def run_cmd(argument_list, output_file = None):
    print "arguments", argument_list
    p = subprocess.Popen(argument_list, stdout=subprocess.PIPE)

    content = ""
    while True:
        line = p.stdout.read(50)

        if not line:
            break

        content += line

    if output_file:
        fout = file(output_file, "w")
        fout.write(content)
        fout.close()

    return content


output = run_cmd(["/usr/bin/svn", "--ignore-externals", "co", svn_url, src_folder] )

以下是一些可能有用的信息:

  1. 要签出的文件数:大约 3000 个
  2. 结帐所需时间:大约 5-6 秒(仅基于文件的 SVN 位置)
  3. python 版本:2.6.4
  4. django 版本:1.1.2
  5. mod wsgi 版本:3.3

我已经坚持了几个小时,非常感谢任何提示!

谢谢。

【问题讨论】:

  • svn_url 是否包含用户名和密码?部署网络服务器以测试服务器的同一用户身份运行?
  • 不,这是一个基于文件的 svn 位置,所以不需要用户名和密码。
  • 测试环境和部署webserver进程在同一个用户下运行?如果没有,请在运行“manage.py runserver”之前尝试su 给运行部署网络服务器的同一用户。
  • 是的,完全相同的服务器和相同的用户。我可以确认 svn 命令的用户身份,因为 Popen 创建的文件夹与我的 runserver 的用户名相同。而且输出不完整,但确实有部分输出和文件夹。
  • popen 很棘手,你应该尝试一些子进程的包装,比如PBS

标签: python django svn wsgi popen


【解决方案1】:

好的,今天又挣扎了3个小时。我终于解决了这个问题。

这是怎么回事,wsgi 和 popen 其实没问题,真正的问题是一些用于签出的源代码文件实际上有特殊字符,并且会破坏 svn 签出过程(出现以下错误)

svn: 无法将字符串从 'UTF-8' 转换为本机编码

wsgi 和控制台对 LC_LANG 有不同的值,这解释了 runserver 和 wsgi 之间的不同行为。

最后,我通过修改'/etc/apache2/envars'的文件并取消注释以下行来解决问题:

。 /etc/default/locale

请注意,您必须通过“apache2ctl stop”和“apache2ctl start”重新启动服务器,而不是“apache2ctl restart”,才能使设置生效。

其实我是用pexpect来找出问题的,但后来因为明显的延迟问题又回到了Popen。

这是我的 run_cmd 的最终代码,希望它可以在未来对其他人有所帮助:

def run_cmd(argument_list, output_file = None):
    print "arguments", argument_list


    #command = " ".join(argument_list)
    #content = pexpect.run(command)
    #if output_file:
        #fout = file(output_file, "w")
        #fout.write(content)
        #fout.close
    #return content

    p = subprocess.Popen(argument_list, bufsize=50, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) #showed error message as well

    content = ""
    while True:
        line = p.stdout.read(50)

        if not line:
            break

        content += line

    #raise Exception(content)   #for debug

    if output_file:
        fout = file(output_file, "w")
        fout.write(content)
        fout.close()

    return content

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    相关资源
    最近更新 更多