1

我正在尝试编写一个校对应用程序,该应用程序从网站上的用户接收证明并将其发送到 Prolog 脚本以检查其有效性。

我正在使用 Django、Python 2.7 和 Sicstus。在我的服务器“view.py”文件中,我调用了一个 python 脚本“checkProof.py”,将用户提交的证明的原始文本形式传递给它。在该文件中,我具有以下功能:

def checkProof(pFile, fFile):
    p = subprocess.Popen(['/bin/bash', '-i', '-c', 'sicstus -l ProofServer/server/proofChecker.pl -- %s %s' % (pFile, fFile)],
        stdout=subprocess.PIPE)
    p.communicate() # Hangs here.

proofChecker.pl 接收修改版本的证明 (pFile),对其进行分析并将反馈输出到反馈文件 (fFile) 中。Python 脚本循环直到生成反馈文件,并将其返回给服务器的其余部分。

我第一次调用这个函数时,一切正常,我得到了预期的输出。我第二次调用这个函数时,程序无限期地挂在“p.communicate()”处。

这意味着,目前,在服务器重新启动之间只能使用应用程序检查一个证明。服务器应该能够在重启之间检查不定数量的证明。

有谁知道为什么会这样?如有必要,我很乐意提供其他信息。

更新

根据下面给出的建议,我尝试了三种不同的调用来确定问题所在。第一个是我正在尝试做的事情——在我真正的校对代码上调用 Sicstus。第二个是调用一个非常简单的 Prolog 脚本来编写硬编码的输出。第三个是一个简单的 Python 脚本,它做同样的事情:

def checkProof(pFile, fFile):
  cmd1 = 'sicstus -l ProofServer/server/proofChecker.pl -- %s %s' % (pFile, fFile)
  cmd2 = 'sicstus -l ProofServer/server/tempFeedback.pl -- %s %s' % (pFile, fFile)
  cmd3 = 'python ProofServer/server/tempFeedback.py %s %s' % (pFile, fFile)
  p = subprocess.Popen(['/bin/bash', '-i', '-c', cmd3],
      stdout=subprocess.PIPE)
  p.communicate() # Hangs here.

在所有三种情况下,应用程序都会继续挂起第二次尝试调用。这意味着问题在于调用 Sicstus,而在于我通常调用程序的方式。这有点让人放心,但我仍然不确定我做错了什么。

4

1 回答 1

1

我最终设法解决了这个问题。

我认为问题在于将 -i (交互式)标志附加到 bash 意味着它需要输入,并且当它没有得到该输入时,它会在第二次调用时暂停进程。这就是尝试用更简单的方法复制该过程时发生的情况。

我摆脱了 -i 标志,发现它现在引发了错误“/bin/bash: sicstus: command not found”,即使 sicstus 在我的服务器的 PATH 上,如果我 ssh 进入服务器,我可以调用它并直接调用它。我通过指定完整路径来解决这个问题。我现在可以在服务器重新启动之间无限次地检查证明,这很棒。我的代码现在是:

def checkProof(pFile, fFile):
  cmd = '/usr/local/sicstus4.2.3/bin/sicstus -l ProofServer/server/proofChecker.pl -- %s %s' % (pFile, fFile)
  p = subprocess.Popen(['/bin/bash', '-c', cmd])
  p.communicate()
于 2014-06-04T15:16:01.923 回答