11

我有一个 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 可执行文件所在的目录。

4

5 回答 5

8

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

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

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

此外,对于已编译的 Haskell 项目,Cabal 构建系统提供了 data-dir 和 data-files 以及相应的生成Paths_<yourproject>.hs文件,用于在运行时为您的项目定位已安装的文件。

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

于 2010-07-26T18:52:35.880 回答
7

有一个FindBin包似乎适合您的需要,它也适用于已编译的程序。

于 2010-07-26T18:48:34.407 回答
6

对于已编译的可执行文件,在 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.) 
于 2013-05-18T19:44:53.383 回答
1

有与我的脚本一起使用的可执行路径。FindBin对我不起作用,因为它返回了我的当前目录而不是脚本目录。runghc

于 2018-08-27T15:07:37.833 回答
0

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

#!/bin/sh

SCRIPT_DIR=`dirname $0`

runhaskell <<EOF
main = putStrLn "My script is in \"$SCRIPT_DIR\""
EOF
于 2010-09-16T14:09:17.207 回答