3

I am trying to run a bash script that has parameters like so:

./test.sh param1 param2

bash file

param1=$1
param2=$2

echo $param1
echo $param2

However it does not work but it will work if the params are not there.

cmd, _ := exec.Command("/bin/sh", fmt.Sprintf("./test.sh %s %s","test1","test2")).Output()

But if I change the bash script to do something else without passing anything into it, then it works.

cmd, _ := exec.Command("/bin/sh", "./test.sh").Output()

How can I pass parameters into a bash file with Go?

4
  • 1
    sh should never be used to run a bash file. sh and bash are two different shells -- even on operating systems where they're symlinked, starting bash under the name sh disables some of its features. Commented Jul 29, 2021 at 17:16
  • 1
    The quotes are not quite right, as can be seen from the syntax highlighting here in the post. Commented Jul 29, 2021 at 17:16
  • Anyhow -- if you were Doing It Right, you'd have a shebang in your script and wouldn't specify an explicit interpreter at all in the caller. Commented Jul 29, 2021 at 17:17
  • That is to say, make the script start with #!/bin/sh (if it's really a sh script instead of a bash script), give it executable permissions, and then start exec.Command('./test.sh', "test1", "test2"). (Ideally, you shouldn't have a .sh extension on the filename either -- see commandname extensions considered harmful for an extensive essay on the topic; using extensions means you can't change your script's interpreter without making the extension misleading or also changing every caller). Commented Jul 29, 2021 at 17:18

1 Answer 1

5

sh expects the name of a script to run as its argument. You don't run sh './test.sh test1 test2' at a shell, you run sh ./test.sh test1 test2. The equivalent to that in Go is:

// KINDA BAD: Doesn't let the script choose its own interpreter
cmd, err := exec.Command("/bin/sh", "./test.sh", "test1", "test2")

If you were passing a shell script as an argument, that would be akin to the shell command sh -c './test.sh test1 test2' -- notice the -c argument. It's very bad practice (introduces serious security bugs), and you shouldn't ever do this, but if you were going to, it would look like:

// VERY BAD: Introduces serious security bugs if arguments are parameterized
cmd, err := exec.Command("/bin/sh", "-c", "./test.sh test1 test2")

But you shouldn't do any of that. Change your script to have a shebang:

#!/bin/sh
param1=$1
param2=$2

echo "$param1"
echo "$param2"

...save it as yourscript (no .sh!), set it to have executable permissions (chmod +x yourscript), and then run:

// GOOD: Lets your script choose its own interpreter
cmd, err := exec.Command("./yourscript", "test1", "test2")
Sign up to request clarification or add additional context in comments.

1 Comment

awesome thanks. I knew it would be simple

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.