Maison > développement back-end > Golang > le corps du texte

Exécuter des scripts bash dynamiques à l'aide de Go, y compris une déclaration de fonction sur une ligne

WBOY
Libérer: 2024-02-05 23:09:11
avant
819 Les gens l'ont consulté

"使用

Contenu de la question

J'écris un exécuteur de tâches bash en go et il a un concept simple :

  1. Il lit taskfile , qui est un script bash contenant une définition de tâche (une simple déclaration de fonction bash)
  2. Il ajoute du contenu supplémentaire de manière dynamique
  3. Exécutez la commande selon les paramètres passés

Voici un exemple simplifié :

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    //simplified for a dynamically built script
    taskfilecontent := "#!/bin/bash\n\ntask:foo (){\n  echo \"test\"\n}\n"
    // simplified for passed arguments
    task := "\ntask:foo"
    bash, _ := exec.lookpath("bash")
    cmd := exec.command(bash, "-c", "\"$(cat << eof\n"+taskfilecontent+task+"\neof\n)\"")
    fmt.println(cmd.string())
    out, _ := cmd.combinedoutput()
    fmt.println(string(out))
}
Copier après la connexion

Mon problème maintenant est que si exécuté via go, cela ne fonctionne pas et j'obtiens cette erreur

task:foo: no such file or directory
Copier après la connexion

Mais si j'exécute le script généré directement dans le shell, ça marche :

$ /opt/opt/homebrew/bin/bash -c "$(cat << EOF
#!/bin/bash

task:foo (){
  echo "test"
}

task:foo
EOF
)"

test   <-- printed out from the `task:foo` above
Copier après la connexion

Qu'est-ce que je fais de mal ici ?


Bonne réponse


Tout d’abord : rien n’a de sens ici.

Vous n’obtiendrez rien que vous n’obtiendrez pas :

cmd := exec.command(bash, "-c", taskfilecontent+"\n"+task)
Copier après la connexion

Si vous l'omettez, votre code sera plus simple.

Deuxième : Expliquez la raison

Lorsque vous exécutez en shell :

65be85239 lit 5

... les éléments entourant les $()" ne sont pas la syntaxe de la copie de bash qui est lancée, mais la syntaxe de la copie de bash qui analyse la commande. /em>. Ils indiquent à la copie de bash que le résultat de la substitution de commande sera transmis sous forme de chaîne, non affecté par le fractionnement de chaîne ou les caractères génériques.

De même, un seul argument pour $(cat <<eofeof 和最终的 )" 也是交互式 shell 的指令,而不是它调用的非交互式 shell。它是运行的交互式 shell cat (包含连接到其标准输入的heredoc内容的临时文件),读取 cat 副本的标准输出,然后将该数据替换为传递给 bash -c.

Dans votre programme go, vous n'avez pas de shell interactif, vous devez donc utiliser la syntaxe go (et non la syntaxe shell) pour effectuer toutes ces étapes. En ce qui concerne ces étapes, il n'y a aucune raison d'aller au premier emplacement (pas besoin d'écrire le fichier de données dans un fichier temporaire, pas besoin de /bin/cat lire le contenu de ce fichier, pas besoin d'utiliser un sous-processus pour exécuter substitution de commande pour générer une chaîne (qui est ensuite placée dans la ligne de commande du shell final), il serait donc plus sage d'ignorer toutes ces étapes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!