我可以从Python运行可执行Haskell文件吗?

pgx2nnw8  于 2023-10-19  发布在  Python
关注(0)|答案(2)|浏览(88)

我有一个Haskell可执行文件(通过使用cabal的build命令),我通过终端中的命令调用它,命令是
cabal run CSVTest
该命令需要在工具的基目录中运行(在这种情况下,我从/home/dayiz/ConfigV运行终端,其中有一个ConfigV.Cabal文件,我给予关于可执行文件的信息)这在控制台中给出了一个输出,我想用Python计算。(如果你好奇这是从哪里来的,我试图使用ConfigV https://github.com/ConfigV/ConfigV的输出来纠正配置文件)
有没有可能给予文件的位置并在Python中运行它?一般的想法是运行我的python工具,决定使用哪个工具来检查文件(在这种情况下,我们使用ConfigV来验证文件。用户将不得不给予他的Haskell可执行文件的路径,他需要在此之前准备),运行该工具并获得输出,然后再次在python中对其进行操作。
我在网上找到的大多数解决方案似乎对我的情况不起作用,因为我不只是执行haskell脚本。该文件需要事先建立与阴谋集团,我找不到任何我的具体情况。ChatGPT给了我几行代码

import subprocess
    haskell_executable = '/home/dayiz/ConfigV/Executables/CSVTest.hs'

    try:
        subprocess.run([haskell_executable], check=True)
    except subprocess.CalledProcessError as e:
        print(f"Error running Haskell executable: {e}")

但是当我尝试使用它时,我得到了OSError:[Errno 8]执行格式错误:/home/dayiz/ConfigV/Executables/CSVTest.hs,我在这一点上迷路了。
谢谢你的帮助

c0vxltue

c0vxltue1#

难道你不需要在这里调用cabal,用文件路径作为参数吗?我认为子进程基本上是在调用文件路径。
https://docs.python.org/3/library/subprocess.html
看了这些文件,我想你想要这样的东西?(capture_output标志表示您希望对脚本的输出执行某些操作)。

subprocess.run(["cabal", "run", "/home/dayiz/ConfigV/Executables/CSVTest.hs"], capture_output=True)
gz5pxeao

gz5pxeao2#

最好的解决方案取决于这是什么样的项目。
最简单的选择是用cabal install安装可执行文件,这将把它放在~/.cabal/bin中。如果你有你的$PATH(可能需要这样说,例如。在您的.bashrc文件中),那么您可以简单地使用

subprocess.run(["CSVTest"], capture_output=True)

我猜你有一个部门

executable CSVTest
  main-is:             CSVTest.hs
  hs-source-dirs:      Executables
  build-depends:       ...

在你的ConfigV.cabal文件中。
从持续集成的Angular 来看,这当然非常可怕。(但如果你的Python生态系统looks anything like mine,那么CI无论如何都是不可能的。
如果你想让代码在某种程度上被包含,你不应该全局安装任何东西。你可以调用cabal run作为“你的Haskell可执行文件”的替代,但是如果你多次调用它的话,效率会很低,因为每一次都需要启动Cabal,它必须完成所有的依赖检查等。
一个更好的解决方案是预编译Haskell代码并使用它,而不从Python调用任何编译。事实上,最好的方法是只将Haskell部分编译成一个对象文件,然后编写一些FFI和C接口,将Python和Haskell世界粘合在一起,但这可能对您的需求来说有点过头了。
编译器只生成带有cabal build的可执行文件。然后你可以使用cabal list-bin CSVTest来找出它把这个可执行文件放在哪里(它会是一些愚蠢的东西,比如/home/Dayiz/ConfigV/dist-newstyle/build/x86_64-linux/ghc-9.4.2/ConfigV-0.1.0.0/x/CSVTest/build/CSVTest/CSVTest)。您可以将其复制/符号链接到更方便的地方,或者只是记下文件名,比如在Python变量csvtest_path中。然后

subprocess.run([csvtest_path], capture_output=True)

相关问题