I need to run a command inside a bash -c "..."
construct. The actual command calls the Vault CLI tool to generate a TLS certificate. The important thing to note is that the CLI tool requires that a variable called VAULT_TOKEN
be set.
For the sake of this example, assume that there are files in the local directory called token
and options
, with data that Vault requires. These are not relevant to the question.
My script:
/bin/bash -c "export VAULT_TOKEN=$(cat token); \
CERT_OPTIONS=$(cat options); \
CERT=\"$(echo \$CERT_OPTIONS | vault write pki/issue/default -format=json -)\"; \
echo cert=\$CERT"
The last statement in the command (echo cert=\$CERT
) is simply a placeholder to demonstrate the problem, normally I would make use the value of $CERT
.
My understanding of how the above should work (based on a very imperfect knowledge of Bash):
- Bash is called and treats the contents of the
"..."
string as a script. That script will then action the below: - Get the token from the file called
token
, export this value into a variable so that sub-processes can access it (hence the use ofexport
). - Get the options from a file and put into a shell variable that is visible at the scope of the contents of the
bash -c
script. - Launch a separate process via command substitution that will call Vault, and
$VAULT_TOKEN
should be visible to this process as it is a child process of the script thatbash -c
runs.
What I see, however, is an error that indicates that $VAULT_TOKEN
is not set, i.e. the vault
CLI tool throws an error saying it doesn't have a value for $VAULT_TOKEN
.
When I simplify the command further to be:
/bin/bash -c "export VAULT_TOKEN=$(echo token); \
CERT=\"$(echo \$VAULT_TOKEN > /tmp/test.out)\"; \
echo cert=\$CERT"
I can see:
> cat /tmp/test.out
$VAULT_TOKEN
...not token
that I was expecting.
I escaped the echo of VAULT_TOKEN
(via echo \$VAULT_TOKEN
), because otherwise I believe that it will be replaced by Bash with the value of $VAULT_TOKEN
from my shell (which is not set), so I get an empty string in /tmp/test.out
.
Clearly my understanding of command substitution/variable evaluation is wrong - please can someone advise on the below:
- Why is
$VAULT_TOKEN
not visible in the$(...)
command substitution? - How do I make
$VAULT_TOKEN
visible to thevault
command?
For other reasons, I must run this set of commands in a bash -c
manner, so I can't separate out the commands into a script.