1

Given this code, I can't figure out how to escape the backtick.

var (
    MY_STRING = "something`something"
)
cmd := fmt.Sprintf("MY_ENV=%q;", MY_STRING)
out, err := exec.Command("bash", "-c", cmd).CombinedOutput()
// results in MY_ENV="something`something" ie unfinished input

I've tried the below but it results in "unknown escape sequence". It does work in the shell obviously. I've also tried to combine strings and raw string literals but with no success. How can I escape the backtick please?

var (
    MY_STRING = "something\`something"
)
rix
  • 10,104
  • 14
  • 65
  • 92
  • Please clearly indicate your error - that error isn't coming from Go itself, which doesn't care about backticks in strings (https://play.golang.org/p/HuxBqxCth1p) so most likely it's coming from your shell. – Adrian Feb 15 '19 at 15:20
  • exit status 1: bash: -c: line 0: unexpected EOF while looking for matching ``' – rix Feb 15 '19 at 15:23
  • Just a note to recommend considering `$(my command)` instead of `\`my command\``. – JGurtz Mar 19 '22 at 20:35

3 Answers3

3

Use ' to escape ` in Bourne shells. And no need to quote the string.

MY_STRING := "something'`'something"
cmd := fmt.Sprintf("MY_ENV=%s;", MY_STRING)
out, err := exec.Command("bash", "-c", cmd).CombinedOutput()
P Varga
  • 19,174
  • 12
  • 70
  • 108
  • “*no need to quote the string*” - `%q` doesn’t just add double quotes, it also adds escape sequences where necessary. – MTCoster Feb 15 '19 at 15:39
  • True but it doesn't escape the string in a way that is useful in a Bourne shell. – P Varga Feb 15 '19 at 15:42
  • @rix https://meta.stackexchange.com/questions/215379/should-drive-by-downvoting-be-more-effectively-caught – P Varga Feb 15 '19 at 15:49
2

The backtick doesn’t need escaping for Go to leave it in the string (ref).

However, bash will treat backticks outside of a string as subshell syntax. The easiest way to escape a backtick in bash is to include it in a single-quoted string:

var MY_STRING = "'something`something'"

But since you’re using %q in your format string, this won’t behave as expected.

Instead, you can use the solution posted on this question. Bash requires double escaping the backtick (\\\`) inside double quotes. There’s a full explanation for why this is necessary in that linked question. Since Go also uses \ as an escape character, you’ll need to double up each one:

var MY_STRING = "something\\\\\\`something"
MTCoster
  • 5,868
  • 3
  • 28
  • 49
  • This doesn't work. It outputs `MY_ENV="something\\`something"` and the shell error is `exit status 1: bash: -c: line 0: unexpected EOF while looking for matching ``'` – rix Feb 15 '19 at 15:25
  • @MTCoster That will still not work because they quote the string below (`%q`), so it will end up being `"'something\`something'"` – P Varga Feb 15 '19 at 15:33
0

you can try //go:embed foo.sh embed external shell file to your code. like this:

    //go:embed yourshell.sh
    var yourshell string

put the shell file in the same folder of your code. details of go embed : https://pkg.go.dev/embed

hnd4r7
  • 7
  • 1
  • 4
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 14 '22 at 14:40