2016-04-08 3 views
0

J'essaie d'exécuter un script shell depuis mon programme go. Je veux démarrer une instance mongo, puis supprimer des données. Ainsi, le script shell ressemblerait à quelque chose comme ceci:Commandes de shell shell golang

mongo 

use test-db 

db.user.remove({"id": 1}) 

J'ai d'abord essayé simplement en utilisant le paquet exec.Command mais il ne chaîne pas les commandes de sorte que le mongo db ferme et je ne peux pas exécuter les autres commandes:

cmd := exec.Command("mongo", "test-db") 
cmd.Start() 
cmd1 := exec.Command("db.remove({\"id\": 1})") 
cmd1.Run() 
cmd.Wait() 

La prochaine chose que j'ai essayé crée une variable et d'essayer d'exécuter ce via sh:

var script = ` 
#!/bin/bash 

mongo 

use test-db 

db.user.remove({"id": 1}) 
` 

et l'exécution exec.Command("sh", script)

Je sais que je peux créer un fichier .sh mais je ne veux pas le faire est-il possible d'enchaîner les commandes dans go pour que mongo db ne se ferme pas et que je puisse exécuter les autres commandes?

Répondre

3

Vous semblez mal comprendre comment les processus (tels que les interprètes et les obus, y compris — it appearsmongodb ainsi) travaillent avec leur soi-disant standard streams: alors que le « test-db » est en effet un argument de passer à un processus mongodb Pour être créé sur sa ligne de commande, le db.user.remove({"id": 1}) est le texte qui a engendré l'instance mongodb est censé lire à partir de son flux d'entrée standard.

vous devez donc essentiellement ceci:

import (
    "os/exec" 
    "strings" 
) 

cmd := exec.Command("mongo", "test-db") 
cmd.Stdin = strings.NewReader(`db.user.remove({"id": 1})\n`) 
err := cmd.Run() 
// Check for an error 

Pour expliquer comment cela fonctionne, nous allons citer les manual:

Stdin spécifie l'entrée standard du processus.
Si Stdin est nil, le processus lit à partir du périphérique null (os.DevNull).
Si Stdin correspond à *os.File, l'entrée standard du processus est directement connectée à ce fichier .
Sinon, pendant l'exécution de la commande, un goroutine distinct lit Stdin et transmet ces données à la commande via un tube. Dans ce cas, Wait ne se termine pas jusqu'à ce que le goroutine arrête la copie, soit parce qu'il a atteint la fin de Stdin (EOF ou une erreur de lecture), soit parce que l'écriture dans le canal a renvoyé une erreur.
Stdin io.Reader

Donc, fondamentalement, vous créez un objet qui prend une chaîne et fournit quelque chose et la mise en œuvre io.Reader « fil » à l'entrée standard du processus sur le point d'être créé. Une fois le processus lancé, os/exec s'assurera de générer un goroutine qui débloquera les données entre votre chaîne et l'instance mongodb en cours d'exécution comme si vous lanciez manuellement mongodb et que vous tapiez cette chaîne directement sur son flux d'entrée standard.

Notez que vous pourriez avoir besoin de vérifier ce que mongodb génère sur son niveau sortie flux — en particulier stderr, — parce que si elle rencontre des erreurs lors de l'exécution du script que vous avez soumis, il sera probablement de les signaler là.