0

In shell, I'm running into the following problem and I'm trying to understand why it behaves this way.

sh-4.4# export VAR='--scan "**/*.jar"'
sh-4.4# set -x
sh-4.4# echo $VAR
+ echo --scan '"**/*.jar"' <--- this
--scan "**/*.jar"

For the executed command, why is there single quotes around the double quoted value?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
tomato
  • 831
  • 5
  • 15
  • 33
  • 5
    Those are added by the `set -x` display, to indicate that the double-quotes and asterisks are literally part of the string, not shell syntax; see [this answer on the Unix & Linux stackexchange](https://unix.stackexchange.com/questions/118403/why-does-bash-add-single-quotes-to-unquoted-failed-pathname-expansions-in-a-comm/118466#118466). – Gordon Davisson Jul 15 '21 at 20:07
  • 2
    You should almost certainly be using an array `VAR=(--scan "**/*.jar")` instead. – chepner Jul 15 '21 at 20:16
  • See [this question](https://stackoverflow.com/questions/12136948/why-does-shell-ignore-quoting-characters-in-arguments-passed-to-it-through-varia) (especially Jonathan Leffler's answer) for more info about how & why to use arrays for things like this. (But don't use `eval` -- that way lies madness.) – Gordon Davisson Jul 15 '21 at 22:33
  • Thanks! Follow up question, what's the best way to pass an array defined in a separate script back to the calling script? The one way I found is to call it like this `. ./myscript.sh`, discussed in the [this](https://stackoverflow.com/questions/1464253/global-environment-variables-in-a-shell-script) first answer's first comment. Are there better ways? – tomato Jul 16 '21 at 01:00
  • The `.` (or equivalently `source`) method is probably simplest. Another option is to print the items with NULL characters as delimiters (like `printf '%s\0' "${args[@]}"`), and read them in the parent with something like `readarray -t -d '' argarray < <(./myscript.sh)`. – Gordon Davisson Jul 16 '21 at 02:46

0 Answers0