


Execute dynamic bash scripts using Go, including a one-line function declaration
I am writing a bash task runner using go, which has a simple concept:
- It reads
taskfile
which is a bash script containing a task definition (a simple bash function declaration) - It adds additional content dynamically
- Execute the command according to the passed parameters
This is a simplified example:
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)) }
My problem now is that if executed via go it doesn't work and I get this error
task:foo: no such file or directory
But if I execute the generated script directly in the shell, it does work:
$ /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
What am I doing wrong here?
Correct Answer
First of all: it doesn’t make any sense here.
You won't get anything you won't get:
cmd := exec.command(bash, "-c", taskfilecontent+"\n"+task)
If you omit it, your code will be simpler.
Second: Explain reason
When you run in the shell:
65be85239 bed 5...The "
s surrounding $()
are not the syntax of the copy of bash that is starting, but the syntax of the copy of bash that is parsing the command. They are Tells the copy of bash that the result of command substitution will be passed as a string, unaffected by string splitting or wildcards.
Similarly, $(cat <<eof
, eof
and finally )"
is also a command of the interactive shell, rather than what it calls A non-interactive shell. It is an interactive shell that runs cat
(a temporary file containing the contents of a heredoc connected to its standard input), reads a copy of cat
's standard output, and then Replace this data with the single argument passed to bash -c
.
In your go program, you don't have an interactive shell, so you should use go syntax (not shell syntax) to perform all these steps. As far as these steps are concerned, there is no reason to go to the first location (there is no need to write the data file to a temporary file, there is no need to let /bin/cat
read the contents of that file, there is no need to use sub The process runs command substitution to generate a string (consisting of these contents) which is then placed on the command line of the final shell), so it would be wiser to ignore all these steps.
The above is the detailed content of Execute dynamic bash scripts using Go, including a one-line function declaration. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

This article explains Go's package import mechanisms: named imports (e.g., import "fmt") and blank imports (e.g., import _ "fmt"). Named imports make package contents accessible, while blank imports only execute t

This article explains Beego's NewFlash() function for inter-page data transfer in web applications. It focuses on using NewFlash() to display temporary messages (success, error, warning) between controllers, leveraging the session mechanism. Limita

This article details efficient conversion of MySQL query results into Go struct slices. It emphasizes using database/sql's Scan method for optimal performance, avoiding manual parsing. Best practices for struct field mapping using db tags and robus

This article explores Go's custom type constraints for generics. It details how interfaces define minimum type requirements for generic functions, improving type safety and code reusability. The article also discusses limitations and best practices

This article demonstrates creating mocks and stubs in Go for unit testing. It emphasizes using interfaces, provides examples of mock implementations, and discusses best practices like keeping mocks focused and using assertion libraries. The articl

This article details efficient file writing in Go, comparing os.WriteFile (suitable for small files) with os.OpenFile and buffered writes (optimal for large files). It emphasizes robust error handling, using defer, and checking for specific errors.

The article discusses writing unit tests in Go, covering best practices, mocking techniques, and tools for efficient test management.

This article explores using tracing tools to analyze Go application execution flow. It discusses manual and automatic instrumentation techniques, comparing tools like Jaeger, Zipkin, and OpenTelemetry, and highlighting effective data visualization
