0

A demonstrate script in bash build.sh is likes:

#!/bin/bash
EXTRA_FLAG="-ldflags=\"-H windowsgui\""
# EXTRA_FLAG="-ldflags='-H windowsgui'"
# EXTRA_FLAG='-ldflags="-H windowsgui"'
# EXTRA_FLAG=-ldflags\="-H windowsgui"

go build ${EXTRA_FLAG}

I want to get the result command like: go build -ldflags="-H windowsgui", but none of these variables works as expected, which giving result like:

go build '-ldflags="-H' 'windowsgui"'
# go build '-ldflags='\''-H' 'windowsgui'\'''
# go build '-ldflags="-H' 'windowsgui"'
# go build -ldflags=-H windowsgui

Seems the auto-generated single quote (') breaks the command, then what is the correct way to define a variable like this?

GeeMing
  • 1
  • 2
  • The demonstration script was obviously written with POSIX shell in mind. In `bash` (or zsh, or ksh), you would use an array instead. – user1934428 Jan 07 '22 at 11:20
  • The demonstration script will not work in any POSIX or posix-like shell, because quotes in variables' values are treated as data, not shell syntax (the single-quotes you see are an *indication* of this, not the cause). This looks like a duplicate of ["Why does shell ignore quoting characters in arguments passed to it through variables?"](https://stackoverflow.com/questions/12136948/why-does-shell-ignore-quotes-in-arguments-passed-to-it-through-variables) (Warning: avoid all suggestions involving `eval` -- that way lies madness and really weird bugs.) – Gordon Davisson Jan 07 '22 at 11:57

1 Answers1

1

Use arrays, and as always quote parameter expansions to avoid word splitting and pathname expansion ):

extra_flags=("-ldflags=-H windowsgui" "opt2" "opt3" "optN")
go build "${extra_flags[@]}"

It's worth noting that:

go build -ldflags="-H windowsgui"

and

go build "-ldflags=-H windowsgui"

is effectively the same. As the go executable will get three arguments, go, build and -ldflags=-H windowsgui and then parse the third argument itself.

Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
  • Assuming that the _demonstration script_ which the OP posted is correct (and the OP wanted to achieve the **same** effect), note that the value of `EXTRA_FLAG` contains a space, and that in this example `$EXTRA_FLAG` is passed **unquoted**, which in turn means that the author of that demonstartion does want word splitting to occur, if he is thinking in terms of sh or bash. This is a different effect to what the OP claimed that he wants to achieve. So, either that demonstration script is already broken, or the OP does not know what he wants. I suspect the former. – user1934428 Jan 07 '22 at 11:23
  • OP mentions that they want to run the command `go build -ldflags="-H windowsgui"` which is what I provide a sane way to do. – Andreas Louv Jan 07 '22 at 11:37
  • Yes, and most likely, your approach is the desired one. I just wanted to point out that what the OP claims to be a "reference" (i.e. his "demonstration script") is doint something different. That's why I suspected that the demonstration code is already broken. – user1934428 Jan 07 '22 at 12:03
  • @Andreas Louv's solution do works on OP's demo script, but what if I still want to keep the `"` inside the argument? Giving another example regardless of go build: `WORDS=('he said, "Hello, everyone!"')` `echo ${WORDS[@]}` the terminal will print result `he said, "Hello, everyone!"` as expected, however, using `set -x`, it can tell it's `word splitting` in to **3** args: `echo he said, '"Hello,' 'everyone!"'` which I may want it to be just single **one** string passing to `echo`; And as @user1934428 mentions, my "script broken", did I mislead or missing something up? – GeeMing Jan 10 '22 at 03:29
  • Add the quotes, escape as needed, and expand inside qoutes. – Andreas Louv Jan 10 '22 at 08:04