0

Consider the following simple function.

X() {
 echo "$1"
 echo "$2"
 echo "$3"
}

Now consider the following variable:

args="-H 'h1 : v1'"

When I run the command X $args, I get the following output:

-H
'h1
:

On the other hand, if I run the command X -H 'h1 : v1', I get the following output:

-H
h1 : v1

Note that, in the latter case, the quotes inside the variable's value are correctly interpreted as delimiters.

Is it possible to modify either the declaration of the variable or the invocation with a variable to force the two outputs above to be equivalent?

merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • Quotes that are data do not substitute for missing quotes that are syntax. – Charles Duffy Aug 24 '21 at 23:58
  • The right way to solve this is to store lists of strings _in arrays_, not strings. – Charles Duffy Aug 24 '21 at 23:59
  • That is: `args=( -H 'h1 : v1' )`, and then `X "${args[@]}"`. – Charles Duffy Aug 24 '21 at 23:59
  • Re: `X -H 'h1 : v1'` -- you aren't showing quotes inside a variable's value being honored. Where's the variable in your example? – Charles Duffy Aug 25 '21 at 00:02
  • 1
    `$2` never contained the quotes. The shell used them to see `h1 : v1` as a single word, rather than 3 separate words, then assigned that single word to the positional parameter. – chepner Aug 25 '21 at 00:03
  • To restate what chepner said in a slightly different way: When a shell starts a program (any program, written in any language), it passes an array of C strings to that program; those C strings become `$0`, `$1`, `$2`, etc in bash, or `sys.argv[0]`, `sys.argv[1]`, etc in Python, or some other equivalent in any other language. So when you run `X 'h1 : v1'`, the array in JSON syntax is `["X", "h1 : v1"]` -- note that the only quotes there are JSON syntax; the single quotes that were there as part of the shell syntax are completely gone[...] – Charles Duffy Aug 25 '21 at 00:04
  • [...] because they were consumed by the shell you entered the string `X 'h1 : v1'` into as it parsed that string. – Charles Duffy Aug 25 '21 at 00:06

1 Answers1

2

This is what arrays are for.

$ args=(-H 'h1: v1')
$ printf '%s\n' "${args[@]}"
-H
h1 : v1
chepner
  • 497,756
  • 71
  • 530
  • 681
  • If the reason for this to be an answer is that we don't have an adequately explicit / focused duplicate to close it with, I wonder if we need to build a canonical instance for the purpose; it certainly comes up often enough. – Charles Duffy Aug 25 '21 at 00:02
  • I've lost hope that any single answer is going to be nuanced enough for many of these questions. – chepner Aug 25 '21 at 00:04