Comment obtenir le répertoire du fichier en cours d'exécution?

Dans nodejs j'utilise _ _ dirname . Quel est L'équivalent de cela à Golang?

J'ai googlé et trouvé cet article http://andrewbrookins.com/tech/golang-get-directory-of-the-current-file/ . Où il utilise le code ci-dessous

_, filename, _, _ := runtime.Caller(1)
f, err := os.Open(path.Join(path.Dir(filename), "data.csv"))

Mais est-ce la bonne façon ou la façon idiomatique de faire à Golang?

156
go
demandé sur Flimzy 2013-08-30 20:07:42

5 réponses

Cela devrait le faire:

import (
    "fmt"
    "log"
    "os"
    "path/filepath"
)

func main() {
    dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
    if err != nil {
            log.Fatal(err)
    }
    fmt.Println(dir)
}
151
répondu Gustavo Niemeyer 2013-08-30 16:44:13

EDIT: à partir de Go 1.8 (publié en février 2017), la façon recommandée de le faire est avec os.Executable:

func Executable() (string, error)

Exécutable renvoie le nom du chemin d'accès de l'exécutable qui a démarré le processus en cours. Il n'y a aucune garantie que le chemin pointe toujours vers l'exécutable correct. Si un lien a été utilisé pour démarrer le processus, selon le système d'exploitation, le résultat pourrait être le lien ou le chemin d'accès il souligné. Si un résultat stable est nécessaire, Chemin/Chemin de fichier.EvalSymlinks pourrait aider.

, Pour obtenir le répertoire de l'exécutable que vous pouvez utiliser path/filepath.Dir.

Exemple:

package main

import (
    "fmt"
    "os"
    "path/filepath"
)

func main() {
    ex, err := os.Executable()
    if err != nil {
        panic(err)
    }
    exPath := filepath.Dir(ex)
    fmt.Println(exPath)
}

ANCIENNE RÉPONSE:

, Vous devriez être en mesure d'utiliser os.Getwd

func Getwd() (pwd string, err error)

Getwd renvoie un nom de chemin enraciné correspondant au répertoire courant. Si le répertoire courant peut être atteint via plusieurs chemins (en raison de liens symboliques), Getwd peut renvoyer l'un d'entre eux.

Par exemple:

package main

import (
    "fmt"
    "os"
)

func main() {
    pwd, err := os.Getwd()
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    fmt.Println(pwd)
}
194
répondu Intermernet 2017-07-24 10:01:38

Utiliser le paquet osext

Il fournit la fonction ExecutableFolder() qui renvoie un chemin absolu vers le dossier où réside l'exécutable du programme en cours d'exécution (utile pour les travaux cron). Il est multi-plateforme.

Documentation en Ligne

package main

import (
    "github.com/kardianos/osext"
    "fmt"
    "log"
)

func main() {
    folderPath, err := osext.ExecutableFolder()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(folderPath)
}
48
répondu Dobrosław Żybort 2015-02-23 08:04:40
filepath.Abs("./")

Abs Renvoie une représentation absolue du chemin. Si le chemin n'est pas absolute il sera rejoint avec le répertoire de travail actuel pour tourner dans un chemin d'accès absolu.

Comme indiqué dans le commentaire, cela renvoie le répertoire qui est actuellement actif.

3
répondu Acidic 2018-01-16 05:37:35

Si vous utilisez package osext par kardianos et vous devez tester localement, comme Derek Dowling a commenté:

Cela fonctionne bien jusqu'à ce que vous souhaitiez l'utiliser avec go run main.aller pour le développement local. Je ne sais pas comment mieux contourner cela sans construire un exécutable à l'avance à chaque fois.

La solution à cela est de faire un gorun.utilitaire exe au lieu d'utiliser Go run. Le gorun.l'utilitaire exe compilerait le projet en utilisant "go build" , puis l'exécuterait juste après, dans le répertoire normal de votre projet.

J'ai eu ce problème avec d'autres compilateurs et je me suis retrouvé à faire ces utilitaires car ils ne sont pas livrés avec le compilateur... c'est particulièrement mystérieux avec des outils comme C où vous devez compiler et lier, puis l'exécuter (trop de travail).

Si quelqu'un aime mon idée de gorun.exe (ou elf) je vais probablement le télécharger sur GitHub bientôt..

Désolé, cette réponse est conçue comme un commentaire, mais je ne peux pas commenter parce que je n'ai pas réputation assez grande encore.

Alternativement ," Go run "pourrait être modifié (s'il n'a pas déjà cette fonctionnalité) pour avoir un paramètre tel que" go run-notemp " pour ne pas exécuter le programme dans un répertoire temporaire (ou quelque chose de similaire). Mais je préférerais simplement taper gorun ou " gor " car il est plus court qu'un paramètre alambiqué. Gorun.exe ou gore.exe devrait être installé dans le même répertoire que votre compilateur go

Implémentation de gorun.exe (ou gore.exe) serait trivial, comme je l'ai ils l'ont fait avec d'autres compilateurs en seulement quelques lignes de code... (célèbres derniers mots ; -)

2
répondu Another Prog 2017-04-18 13:13:56