Führen Sie dynamische Bash-Skripte mit Go aus, einschließlich einer einzeiligen Funktionsdeklaration

WBOY
Freigeben: 2024-02-05 23:09:11
nach vorne
820 Leute haben es durchsucht

"使用

Frageninhalt

Ich schreibe einen Bash-Task-Runner in Go und er hat ein einfaches Konzept:

  1. Es lautet taskfile, ein Bash-Skript, das eine Aufgabendefinition (eine einfache Bash-Funktionsdeklaration) enthält
  2. Es fügt dynamisch zusätzliche Inhalte hinzu
  3. Führen Sie den Befehl gemäß den übergebenen Parametern aus

Hier ist ein vereinfachtes Beispiel:

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))
}
Nach dem Login kopieren

Mein Problem ist jetzt, dass es bei der Ausführung über go nicht funktioniert und ich diese Fehlermeldung erhalte

task:foo: no such file or directory
Nach dem Login kopieren

Aber wenn ich das generierte Skript direkt in der Shell ausführe, funktioniert es:

$ /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
Nach dem Login kopieren

Was mache ich hier falsch?


Richtige Antwort


Zuallererst: Hier ergibt nichts einen Sinn.

Du bekommst nichts, was du nicht bekommst:

cmd := exec.command(bash, "-c", taskfilecontent+"\n"+task)
Nach dem Login kopieren

Wenn Sie es weglassen, wird Ihr Code einfacher.

Zweitens: Erklären Sie den Grund

Wenn Sie im Shell laufen:

65be85239 Bett 5

...die Dinge rund um $()"s sind nicht die Syntax der Bash-Kopie, die gestartet wird, sondern die Syntax der Bash-Kopie, die den Befehl analysiert. /em>. Sie teilen der Bash-Kopie mit, dass das Ergebnis der Befehlsersetzung als String übergeben wird, unbeeinflusst von String-Splitting oder Platzhaltern.

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

In Ihrem Go-Programm haben Sie keine interaktive Shell, daher sollten Sie die Go-Syntax (nicht die Shell-Syntax) verwenden, um alle diese Schritte auszuführen. Was diese Schritte betrifft, gibt es keinen Grund, zum ersten Speicherort zu gehen (keine Notwendigkeit, die Datendatei in eine temporäre Datei zu schreiben, keine Notwendigkeit, den Inhalt dieser Datei gelesen zu haben, keine Notwendigkeit, einen Unterprozess zur Ausführung zu verwenden Befehlsersetzung, um eine Zeichenfolge zu generieren (die dann in die Befehlszeile der endgültigen Shell eingefügt wird), daher wäre es klüger, alle diese Schritte zu ignorieren. /bin/cat

Das obige ist der detaillierte Inhalt vonFühren Sie dynamische Bash-Skripte mit Go aus, einschließlich einer einzeiligen Funktionsdeklaration. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!