1

This might not even be possible but I've been researching for the past hour and come up blank. I have a bash script that gives me a certain output and I want to add that output to Golang in order to redirect a website based on the output of the bash script. Sorry if this makes no sense, im new to Go

Here is what I have to run the bash script and output the value

 func main() {
    out, err := exec.Command("/bin/sh", "script.sh").Output()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf(string(out))
}

I then want to use the value that was output there in another function and to redirect a URL heres how I would redirect to a url and I wanted the $variable to be added. This is just an example I copied off the internet but its what I want to replicate.

func redirect(w http.ResponseWriter, r *http.Request) {

    http.Redirect(w, r, "**$variable**", 301)
}
 func main() {
     http.HandleFunc("/", redirect)
     err := http.ListenAndServe(":8080", nil)
     if err != nil {
         log.Fatal("ListenAndServe: ", err)
     }
 }
1
  • At what moment is your bash script run? At startup? Commented Jan 11, 2022 at 18:50

1 Answer 1

1

Assuming your script must be only run once at startup, then this should do the trick:

var redirectTo string

func redirect(w http.ResponseWriter, r *http.Request) {
    http.Redirect(w, r, redirectTo, 301)
}

func main() {
    out, err := exec.Command("/bin/sh", "script.sh").Output()
    if err != nil {
       log.Fatal(err)
    }
    redirectTo = string(out)
    http.HandleFunc("/", redirect)
    err = http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

Or if you don't want to have a global variable you can generate the redirect function at runtime:

func main() {
    out, err := exec.Command("/bin/sh", "script.sh").Output()
    if err != nil {
       log.Fatal(err)
    }
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        http.Redirect(w, r, string(out), 301)
    })
    err = http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

if you want to handle when out is empty, you can do:

func redirect(w http.ResponseWriter, r *http.Request) {
    if len(redirectTo) == 0 {
        http.Error(w, "No URL parsed!", 500)
        return
    }
    http.Redirect(w, r, redirectTo, 301)
}

This will return an HTTP error 500 in that case.

You can also simply exit the program instead of serving:

out, err := exec.Command("/bin/sh", "script.sh").Output()
if err != nil {
   log.Fatal(err)
}
if len(out) == 0 {
   log.Fatal("no output was returned from script")
}

You can also add more verifications to out here if you wish, like if it is a correct URL, using net/url package for instance.

Sign up to request clarification or add additional context in comments.

6 Comments

If string(out) has trailing whitespace, then OP will want redirectTo = strings.TrimSpace(string(out)).
Yes you may do that, it depends on if you are certain your script will not add trailing spaces, tabs or \n for instance
When I ran both your solutions I got an error "no new variables on left side of :=" which was pointing to the second err := I saw a solution saying to remove the colon for the second err := Would that cause any issues if I removed it? Other than that your solution worked exactly as I wanted, once I removed that colon. @BenjaminBarrois
@BenjaminBarrois im now getting this error when I open the webpage ERR_TOO_MANY_REDIRECTS: localhost redirected you too many times. is there a way to modify the script to only redirect once it has the out variable? or just a way to avoid that error
You are right I replaced the := by =, because err variable is already declared (sorry I had not tested my code).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.