My service uses environment variables extensively for configuration (mostly because it's really easy to inject those into a Docker container). I also have some maintenance scripts that I can run against my production environment. But since I really don't want my shell environment configured to talk to prod by default, I have a helper script instead that sets up the environment and then calls my maintenance script. The helper script currently looks something like this:#!/bin/bashexport DB_NAME=fooexport DB_HOST=foo.service.localexport DB_USERNAME=testy_testersonexport DB_PASSWORD=passwordexport SERVICE_API_KEY=qwertyuiop$@And I run it like bin/production_env.sh scripts/maintenance_script.sh arg1 arg2. That all works great.One of my maintenance scripts is dump_db.sh, which looks like this:#!/bin/shpg_dump --no-owner --clean --if-exists --dbname $DB_NAME --host $DB_HOST --port $DB_PORT --username $DB_USER > db/${RAILS_ENV}-dump.$(date +%Y-%m-%dT%H:%M:%S).sqlThat works great, too. But I'd like to be able to run ad-hoc commands using the configured environment without putting that logic into a script file first. e.g.,bin/production_env.sh psql --username $DB_USER --command 'select version()'The problem, of course, is that the DB_USER variable is expanded in my current shell, before the correct DB_USER variable is available.Is there a convenient way to run ad-hoc commands like this, deferring expansion of variables until the subshell? Or is putting my ad-hoc commands into a script the easiest way?
Defer variable expansion to subshell
bash;shell script;shell;variable;variable substitution
Use eval on your final line, and make sure the parent shell doesn't eat the $:#!/bin/bashexport FOO=barexport BAR=bazeval $@run like so:wouter@gangtai:~$ ./foo.sh echo '$BAR'bazFor more information, see help eval.