Heim  >  Artikel  >  Backend-Entwicklung  >  Führen Sie dynamische Bash-Skripte mit Go aus, einschließlich einer einzeiligen Funktionsdeklaration

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

WBOY
WBOYnach vorne
2024-02-05 23:09:11821Durchsuche

"使用

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))
}

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

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

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)

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen