Ich schreibe einen Bash-Task-Runner in Go und er hat ein einfaches Konzept:
taskfile
, ein Bash-Skript, das eine Aufgabendefinition (eine einfache Bash-Funktionsdeklaration) enthält 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?
Du bekommst nichts, was du nicht bekommst:
cmd := exec.command(bash, "-c", taskfilecontent+"\n"+task)
Wenn Sie es weglassen, wird Ihr Code einfacher.
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 <<eof
、eof
和最终的 )"
也是交互式 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!