2010-07-26 8 views
9

Mam skrypt Haskell, który działa za pośrednictwem linii shebang przy użyciu narzędzia runhaskell. Np ...Jak określić katalog, w którym działa uruchomiony skrypt lub aplikacja Haskell?

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

Teraz chciałbym być w stanie określić katalog, w którym rezyduje że skrypt od wewnątrz skryptu, sama. Tak więc, jeśli skrypt będzie działał w /home/me/my-haskell-app/script.hs, powinienem móc uruchomić go z dowolnego miejsca, używając względnej lub bezwzględnej ścieżki, i powinien wiedzieć, że znajduje się w katalogu /home/me/my-haskell-app/.

Myślałem, że funkcjonalność dostępna w module System.Environment może być pomocna, ale trochę się skróciła. getProgName nie zapewniało użytecznych informacji o ścieżce pliku. Odkryłem, że zmienna środowiskowa _ (to podkreślenie) oznaczałaby ścieżkę do skryptu, ponieważ została wywołana; jednakże, jak tylko skrypt zostanie wywołany przez jakiś inny program lub skrypt macierzysty, ta zmienna środowiskowa wydaje się tracić swoją wartość (i potrzebuję wywołać mój skrypt Haskell z innej, macierzystej aplikacji).

Warto również wiedzieć, czy mogę określić katalog, w którym żyje skompilowany plik wykonywalny Haskell, używając tej samej techniki lub w inny sposób.

Odpowiedz

6

Istnieje pakiet FindBin, który wydaje się pasować do twoich potrzeb i działa również w przypadku skompilowanych programów.

8

Jak rozumiem, jest to historycznie trudne w * nix. Istnieją biblioteki dla niektórych języków w celu zapewnienia takiego zachowania, w tym FindBin dla Haskell:

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

Nie jestem pewien, co to będzie raport ze skryptem chociaż. Prawdopodobnie lokalizacja pliku binarnego, który runhaskell został skompilowany tuż przed jego wykonaniem.

Ponadto, dla skompilowanych projektów Haskell, system budujący Cabal zapewnia katalog danych i pliki danych oraz odpowiadający im wygenerowany Paths_<yourproject>.hs do lokalizowania zainstalowanych plików dla projektu w czasie wykonywania.

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

+1

Pakiet FindBin wydaje się również działać poprawnie w przypadku skryptów opartych na runhaskell. –

0

nie mogłem znaleźć sposób, aby określić ścieżkę skryptu z Haskell (który jest prawdziwym szkoda IMHO). Jednak, jak obejść ten problem, można owinąć skrypt Haskell wewnątrz skryptu powłoki:

#!/bin/sh 

SCRIPT_DIR=`dirname $0` 

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

Dla skompilowanych plików wykonywalnych, w GHC 7.6 lub nowszej można korzystać 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.) 
Powiązane problemy