如何确定正在运行的 Haskell 脚本或应用程序所在的目录?

发布于 2024-09-11 15:19:48 字数 597 浏览 4 评论 0原文

我有一个 Haskell 脚本,它使用 runhaskell 实用程序通过 shebang 线运行。例如..

#! /usr/bin/env runhaskell
module Main where
main = do { ... }

现在,我希望能够从脚本本身中确定该脚本所在的目录。因此,如果脚本位于 /home/me/my-haskell-app/script.hs 中,我应该能够使用相对或绝对路径从任何地方运行它,并且它应该知道它位于 /home/me/my-haskell-app/ 目录中。

我认为 System.Environment 模块中提供的功能可能会有所帮助,但它有点不足。 getProgName 似乎没有提供有用的文件路径信息。我发现环境变量 _ (这是一个下划线)有时会包含脚本被调用时的路径;但是,一旦通过其他程序或父脚本调用该脚本,该环境变量似乎就会失去其值(并且我需要从另一个父应用程序调用我的 Haskell 脚本)。

同样有用的是我是否可以使用相同的技术或其他技术来确定预编译的 Haskell 可执行文件所在的目录。

I have a Haskell script that runs via a shebang line making use of the runhaskell utility. E.g...

#! /usr/bin/env runhaskell
module Main where
main = do { ... }

Now, I'd like to be able to determine the directory in which that script resides from within the script, itself. So, if the script lives in /home/me/my-haskell-app/script.hs, I should be able to run it from anywhere, using a relative or absolute path, and it should know it's located in the /home/me/my-haskell-app/ directory.

I thought the functionality available in the System.Environment module might be able to help, but it fell a little short. getProgName did not seem to provide useful file-path information. I found that the environment variable _ (that's an underscore) would sometimes contain the path to the script, as it was invoked; however, as soon as the script is invoked via some other program or parent script, that environment variable seems to lose its value (and I am needing to invoke my Haskell script from another, parent application).

Also useful-to-know would be whether I can determine the directory in which a pre-compiled Haskell executable lives, using the same technique or otherwise.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

苄①跕圉湢 2024-09-18 15:19:48

有一个 FindBin 包似乎可以满足您的需求,并且它也适用于已编译的程序。

There is a FindBin package which seems to suit your needs and it also works for compiled programs.

栀子花开つ 2024-09-18 15:19:48

据我了解,这在 *nix 中历来是很棘手的。有些语言的库可以提供这种行为,包括 Haskell 的 FindBin:

http://hackage.haskell.org /package/FindBin

不过,我不确定这会通过脚本报告什么。可能是 runhaskell 在执行之前编译的二进制文件的位置。

此外,对于已编译的 Haskell 项目,Cabal 构建系统提供数据目录和数据文件以及相应生成的 Paths_.hs,用于在运行时查找项目的已安装文件。

http://www.haskell .org/cabal/release/cabal-latest/doc/users-guide/authors.html#paths-module

As I understand it, this is historically tricky in *nix. There are libraries for some languages to provide this behavior, including FindBin for Haskell:

http://hackage.haskell.org/package/FindBin

I'm not sure what this will report with a script though. Probably the location of the binary that runhaskell compiled just prior to executing it.

Also, for compiled Haskell projects, the Cabal build system provides data-dir and data-files and the corresponding generated Paths_<yourproject>.hs for locating installed files for your project at runtime.

http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#paths-module

心在旅行 2024-09-18 15:19:48

对于已编译的可执行文件,在 GHC 7.6 或更高版本中,您可以使用 System.Environment.getExecutablePath

getExecutablePath :: IO FilePathSource

  Returns the absolute pathname of the current executable.
  Note that for scripts and interactive sessions, this is the path to the
  interpreter (e.g. ghci.) 

For compiled executables, In GHC 7.6 or later you can use System.Environment.getExecutablePath.

getExecutablePath :: IO FilePathSource

  Returns the absolute pathname of the current executable.
  Note that for scripts and interactive sessions, this is the path to the
  interpreter (e.g. ghci.) 
绝不服输 2024-09-18 15:19:48

executable-path 与我的 runghc 脚本一起使用。 FindBin 对我不起作用,因为它返回了我当前的目录而不是脚本目录。

There is executable-path which worked with my runghc script. FindBin didn't work for me as it returned my current directory instead of the script dir.

始终不够 2024-09-18 15:19:48

我找不到一种方法来确定 Haskell 的脚本路径(恕我直言,这是一个真正的遗憾)。但是,作为解决方法,您可以将 Haskell 脚本包装在 shell 脚本中:

#!/bin/sh

SCRIPT_DIR=`dirname $0`

runhaskell <<EOF
main = putStrLn "My script is in \"$SCRIPT_DIR\""
EOF

I could not find a way to determine script path from Haskell (which is a real pity IMHO). However, as a workaround, you can wrap your Haskell script inside a shell script:

#!/bin/sh

SCRIPT_DIR=`dirname $0`

runhaskell <<EOF
main = putStrLn "My script is in \"$SCRIPT_DIR\""
EOF
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文