我有一个Haskell脚本,它使用runhaskell
实用程序通过shebang行运行。 E.g ...
#! /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可执行文件所在的目录。
答案 0 :(得分:8)
据我了解,这在* nix中历史上很棘手。有些语言的库可以提供这种行为,包括用于Haskell的FindBin:
http://hackage.haskell.org/package/FindBin
我不确定这会用脚本报告什么。可能是runhaskell在执行它之前编译的二进制文件的位置。
此外,对于已编译的Haskell项目,Cabal构建系统提供了data-dir和数据文件以及相应的生成Paths_<yourproject>.hs
,用于在运行时为项目定位已安装的文件。
http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#paths-module
答案 1 :(得分:7)
有一个FindBin软件包似乎适合您的需求,它也适用于已编译的程序。
答案 2 :(得分:5)
对于已编译的可执行文件,在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.)
答案 3 :(得分:0)
我找不到一种方法来确定来自Haskell的脚本路径(这是一个真正可惜的恕我直言)。但是,作为一种变通方法,您可以将Haskell脚本包装在shell脚本中:
#!/bin/sh
SCRIPT_DIR=`dirname $0`
runhaskell <<EOF
main = putStrLn "My script is in \"$SCRIPT_DIR\""
EOF
答案 4 :(得分:0)
有executable-path与我的runghc
脚本一起使用。 FindBin对我不起作用,因为它返回了当前目录而不是脚本目录。