Savoir dans quel répertoire tourne mon application

Pourquoi est-ce important ?

Dans le cas où votre programme golang est lancé en tant que service, il peut être utile d’obtenir l’emplacement de l’exécutable et non le répertoire de travail. Un cas d’usage serait d’accéder à un fichier de configuration qui est dans le même répertoire que l’exécutable ou à un sous-répertoire qui contiendrait des données ou vos templates.

Prenons l’exemple d’une ressource config.json contenue dans le répertoire d’installation de votre programme go. Avec Windows, si vous tentez d’accéder à cette ressource avec le chemin relatif ./config.json, le programme tentera d’accéder à %WinDir%\System32\config.json qui est le répertoire de travail des services Windows.

Ce qu’il ne faut pas faire

On pourrait être tenté d’utiliser os.Getwd(), mais cette fonction ne retournera le bon répertoire que si le programme a été lancé de manière interactive (depuis la console, par exemple) et pas dans le cas d’un service. En outre, si votre programme ou une bibliothèque tierce modifie le répertoire de travail (avec os.Chdir()) le résultat de la fonction ne sera plus valide.

Comme expliqué dans un autre de mes articles, os.Args[0] ne fonctionnera pas forcément à tous les coups.

Comment connaître le répertoire d’exécution du programme en cours d’exécution ?

Il existe une bibliothèque tierce (kardianos/osext) qui est capable de retrouver chemin de l’exécutable golang quel que soit le système d’exploitation (le principe de fonctionnement est décrit plus loin). On installe donc le paquet qui va bien en exécutant ces commandes à la console :

go get bitbucket.org/kardianos/osext
go install bitbucket.org/kardianos/osext

Puis, on inclut ce code en début de fichier :

import "bitbucket.org/kardianos/osext"

La ligne de code permettant de récupérer le chemin de l’exécutable golang est la suivante :

exePath, _ := osext.ExecutableFolder()

Principe de fonctionnement

Sous Linux, on peut obtenir le chemin de l’exécutable golang en lisant dans le répertoire /proc. Par exemple, si votre exécutable a pour PID 41, on obtient son chemin en lisant le lien /proc/41/exe.

pid := os.Getpid() 
lnk := "/proc/" + strconv.Itoa(pid) + "/exe" 
p, err = os.Readlink(lnk)

Sous Windows, il faut faire appel à la fonction GetModuleFileNameW de la bibliothèque kernel32.dll

func getModuleFileName(buflen uint32, buf *uint16) (n uint32, err error) { 
    h, err := syscall.LoadLibrary("kernel32.dll") 
    if err != nil { 
        return 0, err 
    } 
    defer syscall.FreeLibrary(h) 
    addr, err := syscall.GetProcAddress(h, "GetModuleFileNameW") 
    if err != nil { 
        return 0, err 
    } 
    r0, _, e1 := syscall.Syscall(addr, 3, uintptr(0), 
uintptr(unsafe.Pointer(buf)), uintptr(buflen)) 
    n = uint32(r0) 
    if n == 0 { 
        if e1 != 0 { 
            err = error(e1) 
        } else { 
            err = syscall.EINVAL 
        } 
    } 
    return 
}

Étiquettes :   kardianos   thirdparty 
Portrait de Benjamin BALET
Benjamin BALET
Consultant APM

Retrouvez mes cooordonées

Benjamin BALET sur viadeo






Vous aimerez aussi

Comment écrire du code Go ?

Traduction d'une partie des spécifications officielles du langage Go, cet article explique comment développer en Go.   Lire »

Les lois de la réflexion

Une traduction du blog officiel de golang expliquant le mécanisme de la réflexion en Go.   Lire »

Développer, installer et configurer un service golang

Créer et déployer un service golang sous Linux, Windows et MacOS. La bibliothèque kardianos/service permet de créer, lancer et arrêter un service Go   Lire »

Gestion des cas d'erreur Defer, panic et recover

Exemples concrets d'utilisation des fonctions de gestion des erreurs, d'arrêt anormal de l'exécution d'un programe et de récupération.   Lire »

Gobs le format natif d'échange de données en Go

Traduction d'un article du blog officiel expliquant comment échanger des données entre deux programmes golang grâce à un format natif   Lire »

Commentaires

Soyez le premier à commenter cet article

Publier un commentaires

Tous les commentaires sont soumis à modération. Les balises HTML sont pour la plupart autorisées. Les liens contextuels et intéressants sont en follow.

(requis)
(requis)
(requis, mais non publié)
(recommandé si vous souhaitez être publié)