0

I'm trying to execute the following printf statement in a zsh script I'm working on:

printf "%s\n" "${CREATE_WS[@]}"

Where $CREATE_WS is an indexed array as follows:

CREATE_WS=("************************************************************************" \
        "You are about to create the $workspace workspace using the" \
        "version set $versionset. Do you want to continue?" \
        "************************************************************************" \
        " ")

Where $workspace and $versionset are taken from command line arguments. If I echo both variables by themselves, the console shows that they are non-null and have the string that was entered on the command line. However, when the printf statement runs, the variables do not expand into the strings that they contain as expected, and are printed as though they are null.

I've tried wrapping the variables in curly braces like so: ${versionset}. But this also doesn't give me the desired behavior. What have I written wrong in this procedure, and how do I correct it?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 2
    Variables inside strings are expanded when you assign to `CREATE_WS`, not when you use it. – Barmar Jul 02 '21 at 16:53
  • Were the `$workspace` and `$versionset` variables set when you executed the `CREATE_WS=` statement? – Barmar Jul 02 '21 at 16:54
  • Good point. CREATE_WS is a constant that is set at runtime. Since that gets set PRIOR to the script processing command line arguments, those two variables aren't set yet at that point. – Karie Adair Jul 02 '21 at 16:56
  • All variables are set at runtime. You just need to fix the order that they're set. – Barmar Jul 02 '21 at 16:57
  • `${versionset}` and `$versionset` are *identical*; braces are the canonical "spelling" for a parameter expansion, but they can be dropped when doing so will not introduce an ambiguity or result in a different parse. (E.g., `${foo}bar` vs `$foobar`.) – chepner Jul 02 '21 at 17:03
  • The line continuations are unnecessary; the array assignment cannot end without closing the `)`, so the parser will not treat a newline as terminating the command. – chepner Jul 02 '21 at 17:05
  • @Barmar If I define `$versionset` and `$workspace` as empty variables at runtime, prior to defining $CREATE_WS, would that resolve the issue? – Karie Adair Jul 02 '21 at 19:16
  • No, that will just put the empty values into `CREATE_WS`. – Barmar Jul 02 '21 at 19:16
  • Variables aren't templates, they don't fill in placeholders when expanded. – Barmar Jul 02 '21 at 19:17
  • 1
    It sounds like you should write a function, not use variables. – Barmar Jul 02 '21 at 19:18
  • How would you suggest constructing the function? My goal was to centralize as much as my string variables as possible, to make them easier to edit in the future. Obviously, this issues poses a problem to accomplishing that goal. – Karie Adair Jul 02 '21 at 19:41
  • Works for me, although it can be written simpler: Example code (for testing): `CREATE_WS=(a b c); printf "%s\n" $CREATE_WS`. If you don't get the desired output, your array does not contain what you think it does. – user1934428 Jul 05 '21 at 07:31

1 Answers1

1

Try this (note the single quotes):

create_ws_msg=(
  'workspace: $workspace'
  'version: $versionset'
  '***'
  '' )

workspace=ws21
versionset=3.14

print ${(eF)create_ws_msg}

# => workspace: ws21
# => version: 3.14
# => ***
# => 

The variable reference ${...} in the print statement has two parameter expansion flags, in parentheses. e expands nested variables, and F adds newlines. The zshexpn man page has details on these and other flags.


As noted in the comments, you could use a function instead. That may prove easier for a future maintainer to understand, since zsh uses the same syntax as bash.

Using named variables:

function print_create_ws_msg {
  printf '%s\n' \
    "workspace: $workspace" \
    "version: $versionset" \
    '***'
}

workspace='ws42'
versionset='4.2'
print_create_ws_msg

Using positional parameters:

function print_create_ws_msg {
  printf '%s\n' \
    "workspace: $1" \
    "version: $2" \
    '***'
}

print_create_ws_msg 'wsa' '99'
Gairfowl
  • 2,226
  • 6
  • 9