2010-07-26 20 views
9

Tengo un script Haskell que se ejecuta a través de una línea shebang haciendo uso de la utilidad runhaskell. Por ejemplo ...¿Cómo se determina el directorio en el que se ejecuta una secuencia de comandos o aplicación Haskell?

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

Ahora, me gustaría ser capaz de determinar el directorio en el que reside la escritura desde el script, en sí. Entonces, si el script vive en /home/me/my-haskell-app/script.hs, debería poder ejecutarlo desde cualquier lugar, usando una ruta relativa o absoluta, y debería saber que está ubicado en el directorio /home/me/my-haskell-app/.

Pensé que la funcionalidad disponible en el módulo System.Environment podría ayudar, pero se quedó un poco corta. getProgName no parece proporcionar información útil de ruta de archivo. Encontré que la variable de entorno _ (que es un guión bajo) sería a veces contiene la ruta de acceso del guión, tal como se invocó; sin embargo, tan pronto como se invoca el script a través de otro programa o script primario, esa variable de entorno parece perder su valor (y necesito invocar mi script Haskell desde otra aplicación principal).

También es útil saber si puedo determinar el directorio en el que vive un ejecutable Haskell precompilado, utilizando la misma técnica o de otro modo.

Respuesta

6

Hay un paquete FindBin que parece satisfacer sus necesidades y también funciona para programas compilados.

8

Según tengo entendido, esto es históricamente complicado en * nix. Hay bibliotecas para algunos idiomas para proporcionar este comportamiento, incluyendo FindBin de Haskell:

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

No estoy seguro de lo que informará con un guión sin embargo. Probablemente la ubicación del binario que runhaskell compiló justo antes de ejecutarlo.

Además, para los proyectos compilados de Haskell, el sistema de compilación de Cabal proporciona datos dir y archivos de datos y el correspondiente generado Paths_<yourproject>.hs para localizar los archivos instalados para su proyecto en tiempo de ejecución.

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

+1

El paquete FindBin parece funcionar bien también para los scripts basados ​​en runhaskell. –

0

no pude encontrar una manera de determinar la trayectoria de la escritura de Haskell (que es una verdadera lástima en mi humilde opinión). Sin embargo, como solución alternativa, se puede envolver su script Haskell dentro de un script de shell:

#!/bin/sh 

SCRIPT_DIR=`dirname $0` 

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

Por ejecutables compilados, En GHC 7.6 o posterior puede utilizar 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.) 
Cuestiones relacionadas