views:

134

answers:

3

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.

+1  A: 

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

Daniel Velkov
+3  A: 

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

dino
The FindBin package seems to work okay for runhaskell-based scripts too.
Chris W.
A: 

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
devmusings