1

I'm using SaltStack to run a command that contains a Linux enviornment variable inside a string. The environment variable is $DUO. Example:

export DUO="TESTKEY"

I can run a command such as:

salt computer chocolatey.install app args='/S /V" /qn '"$DUO"'"'

This will actually produce a command like:

'/S /V" /qn TESTKEY"'

It outputs the environment variable which is what I want.

I am now running a bash script that gets the environment variable from the user and places it in the string:

#!/bin/bash

echo "What env do you want to use?: "
read env

i="\$${env}"
echo $i
salt computer chocolatey.install app args='/S /V" /qn '"${i@Q}"'"'

My Bash script takes the users input and automatically places a '$' in front of it. If a user enters input of "DUO", the command will run as:

'/S /V" /qn '$DUO'"'

But I want it to run this:

'/S /V" /qn TESTKEY"'

In the Bash script, how can I escape the i variable properly so that it calls the environment variable $DUO when the command runs?

UPDATE

Here is my actual SaltStack command:

sudo salt computername chocolatey.install duo override_args=True install_args='/S /V" /qn HOST="xxxxxxx.com" RDPONLY="#0" '"$DUO"'"'

Output:

computername:
    Chocolatey v0.10.15
    Installing the following packages:
    duo
    By installing you accept licenses for the packages.

    duo v0.3
    duo package files install completed. Performing other installation steps.
    Installing Duo...
    Overriding package arguments with '/S /V" /qn HOST="xxxxxxx.com" RDPONLY="#0" TESTKEY"' (replacing '/S /V" /qn HOST="xxxxxxx.com" RDPONLY="#0" "')
    Duo has been installed.
     The install of duo was successful.
      Software installed as 'EXE', install location is likely default.

    Chocolatey installed 1/1 packages. 
     See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).

UPDATE 2

I ran the script with debugging on and the Bash script is actually running it as:

+ salt 'computername' chocolatey.install duo override_args=True 'install_args=/S /V" /qn HOST="xxxxx.com" RDPONLY="#0" '\''$DUO'\''"'

UPDATE 3

I've tried expanding the variable name and I get an error.

bad substitution

For example, this gives me that error:

#!/bin/bash

echo "What env do you want to use?: "
read env

i="\$${env}"
echo "${!i}"
Kade Williams
  • 1,041
  • 2
  • 13
  • 28
  • `$DUO` is not a valid variable name, and `export $DUO="TESTKEY"` is not a command that assigns such a variable. It needs to be `export DUO="TESTKEY"` (though using all-caps names for your own variables is not a good practice in general -- POSIX reserves names with at least one lowercase character for application use, whereas all-caps variables can modify or reflect behavior of the shell itself or of POSIX-defined tools). – Charles Duffy May 27 '20 at 00:49
  • As for indirect expansion of shell variables, that's documented extensively in [BashFAQ #6](https://mywiki.wooledge.org/BashFAQ/006). `${i@Q}` is only used when you're generating something that's going to be parsed by another shell as syntax. – Charles Duffy May 27 '20 at 00:51
  • Anyhow -- show us a salt command that would behave exactly as you intend (after the expansion has been replaced with a value), and then this will be more clearly answerable. – Charles Duffy May 27 '20 at 00:52
  • Sorry, that was a typo. I've tried shortening everything up. I'll post the actual command and actual output. – Kade Williams May 27 '20 at 00:54
  • Thanks! Actually, what would be even better is to use `set -x` to enable tracing, run a working command, and provide its trace. That way we can see how the shell views the quoting that's used when things work as you expect. (Once you've collected that log, you can use `set +x` to turn tracing back off). – Charles Duffy May 27 '20 at 00:55
  • BTW, once you have `env`, you can use `${!env}` to expand the variable *named in* `$env`; that part of your question we already have duplicates for, f/e, [bash variable variables](https://stackoverflow.com/questions/10757380/bash-variable-variables). It's not clear to me now whether there are other aspects of this question that aren't fully answered there. – Charles Duffy May 27 '20 at 00:57
  • @Barmar, ...are you sure? I do think this is duplicative of other knowledge base entries, but a question couched in terms of RPM macros is not the most obvious choice. Yes, the OP's quoting here is deeply weird, but they're showing a working command that does most of that same deeply-weird quoting, so some level of literal quotes inside the data appear to be required by the command that they're running. Not the case with the proposed duplicate, where any literal-as-opposed-to-syntactic quotes are clearly in error. – Charles Duffy May 27 '20 at 01:06
  • @CharlesDuffy Didn't notice that there was also some variable variable stuff going on here in addition to the quoting issue – Barmar May 27 '20 at 01:09
  • See an `xtrace`-enabled run of their working command at https://ideone.com/koYa5D -- literal as opposed to syntactic double quotes appear to genuinely be expected. Which makes me think that this is a clean duplicate of any how-do-I-use-indirect-expansion? question, since that's the only part that was missing. – Charles Duffy May 27 '20 at 01:11
  • @KadeWilliams, to be clear, I was asking for a `set -x` trace of a *working* command, not a failing one. (Back later, off to dinner). – Charles Duffy May 27 '20 at 01:23
  • `i="\$${env}"` is wrong. Just `${!env}` is right, or `i=$env`, and then `${!i}`, if you *really* want to create a new/separate variable for some weird reason. – Charles Duffy May 27 '20 at 02:38
  • Sorry, I'm confused. I was wanting to actually get a dollar sign in my output. Expanding the variable named as in the example URL gives me the name without a $. I am doing a couple other things to my variable that I did not list. I was trying to make it simple. – Kade Williams May 27 '20 at 03:34
  • Thank you for your help. I've been doing testing with non Chocolatey commands that work. I think my issues actually stem from the way Chocolatey handles my commands. – Kade Williams May 27 '20 at 05:14

1 Answers1

0

Indirect Expansion

As given elsewhere in the knowledgebase, use ${!env} to expand to the variable named in $env.

Using It Here

DUO=TESTKEY
env=DUO
set -x # enable tracing; below : causes us to just trace the command and not run it
: sudo salt computername chocolatey.install duo override_args=True install_args='/S /V" /qn HOST="xxxxxxx.com" RDPONLY="#0" '"${!env}"'"'

...yields the exact same output as your example of a working Chocolatey command with no substitution:

DUO=TESTKEY
set -x # enable tracing; below : causes us to just trace the command and not run it
: sudo salt computername chocolatey.install duo override_args=True install_args='/S /V" /qn HOST="xxxxxxx.com" RDPONLY="#0" '"${DUO}"'"'
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441