【问题标题】:Redirecting Output from Mathematica Script to PIPE Instead of stdout Using subprocess.Popen Yields Null String使用 subprocess.Popen 将输出从 Mathematica 脚本重定向到 PIPE 而不是 stdout 产生空字符串
【发布时间】:2014-02-05 20:54:06
【问题描述】:

我有一个 Mathematica 脚本,我可以将它作为 bash 可执行文件从终端运行。我想从 Python 中运行它并得到结果。这是我想使用的代码:

proc = subprocess.Popen(["./solve.m", Mrefnorm, Mvert, Mcomp, Mangle],
        stdout=subprocess.PIPE,stderr=subprocess.PIPE)
result, err = proc.communicate()

不幸的是,结果是一个空字符串。但是,当我运行此代码时,结果会按预期打印到终端窗口:

proc = subprocess.Popen(["./solve.m", Mrefnorm, Mvert, Mcomp, Mangle],
        stdout=subprocess.sys.stdout,stderr=subprocess.sys.stdout)

我为有 Windows 的人找到了这个 answer,这与我遇到的问题完全相同。不幸的是,他的解决方案与他的防火墙软件沙箱化进程有关。我已经禁用了我的检查是否可以解决它,但它没有。我已经尝试了评论者在他的问题上提到的所有内容,但没有成功。

总的来说,Mathematica 脚本在两种情况下都运行(两种情况都需要大约 5 秒),但是当我使用 PIPE 时,我无法获得脚本的输出。

【问题讨论】:

  • 感谢您的回复;我尝试了该帖子中的解决方案,但我仍然从标准输出的 PIPE 中得到一个空字符串。同时,我正在尝试使用另一台计算机来尝试脚本。
  • 什么是proc.returncode?成功了吗? err 中有什么内容? ./solve.m 中的 shebang 是什么?您在终端中看到任何输出吗?如果没有重定向(stdout/stderr 为None),您是否看到任何输出?您是否尝试过从 bash 复制粘贴成功的命令并使用 subprocess.check_call("./solve.m ...", shell=True) 运行它?您可以在 bash 中重定向输出,例如 ./solve.m ... >some_filesome_file 是否包含正确的输出)?您是否使用了正确的工作目录(cwd 参数)?
  • proc.returncode = 0;错误 = ''; shebang = "#!/Applications/Mathematica.app/Contents/MacOS/MathematicaScript -script";重定向时终端无输出;当 stdout=None 时,终端会显示数学脚本的输出以及数学问题的正确答案。当我直接在 bash 中运行它时,它也可以正常工作。没有重定向的 subprocess.check_call 和在 bash 中工作的相同 shell 命令也可以工作并将结果打印到终端。但是,如果我使用 check_output,它会再次返回一个空字符串,因为它在内部重定向到 PIPE。

标签: python wolfram-mathematica subprocess


【解决方案1】:

原来 Mathematica 9 中存在重定向标准输出的错误。见https://mathematica.stackexchange.com/questions/20954/why-doesnt-my-script-work-when-i-redirect-stdout

【讨论】:

    【解决方案2】:

    如果 Mathematica 不喜欢重定向的标准输出,那么您可以尝试通过提供伪 tty 来欺骗它:

    import pipes
    from pexpect import run # $ pip install pexpect
    
    args = ["./solve.m", Mrefnorm, Mvert, Mcomp, Mangle]
    command = " ".join(map(pipes.quote, args))
    output, status = run(command, withexitstatus=True)
    

    你也可以use stdlib pty module directly to capture the output

    如果你想得到单独的stdout/stderr;你可以尝试解决the bug mentioned by @Wayne Allen

    【讨论】:

      【解决方案3】:

      我不知道为什么会这样,但我让它像这样工作:

       proc=subprocess.Popen('fullpath/math -initfile  fullpath/script.m' ,
              shell=True,
              stdout=subprocess.pipe )
      

      由于某种原因,arg列表的列表形式不起作用,-script也不起作用。

      刚刚检查过你可以传递额外的参数,添加到字符串中就可以了

       proc=subprocess.Popen('fullpath/math -initfile  fullpath/script.m arg1 arg2' ,
              shell=True,
              stdout=subprocess.pipe )
      

      通过$CommandLine访问脚本中的参数

      (mathematica 9, python 2.4.3, redhat)

      【讨论】:

      • 谢谢你的例子。我尝试了它并得到了相同的行为(空管道),所以我很确定我的机器上的安装一定有问题。感谢您的努力。
      猜你喜欢
      • 2014-12-14
      • 1970-01-01
      • 2011-07-22
      • 1970-01-01
      • 2019-05-27
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      相关资源
      最近更新 更多