変数拡張をサブシェルに延期

変数拡張をサブシェルに延期

私のサービスは設定のために環境変数を広く使用しています(主にDockerコンテナに挿入するのは非常に簡単です)。

また、本番環境で実行できるメンテナンススクリプトもあります。しかし、私以来本物デフォルトでは、製品と通信するようにシェル環境を構成するのではなく、環境を設定してからメンテナンススクリプトを呼び出すヘルパースクリプトを使用します。ヘルパースクリプトは現在次のとおりです。

#!/bin/bash
export DB_NAME=foo
export DB_HOST=foo.service.local
export DB_USERNAME=testy_testerson
export DB_PASSWORD=password
export SERVICE_API_KEY=qwertyuiop
"$@"

私はそれをbin/production_env.sh scripts/maintenance_script.sh arg1 arg2。これはすべて良いです。

私のメンテナンススクリプトの1つは次のdump_db.shとおりです。

#!/bin/sh
pg_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).sql"

これも素晴らしい作品です。しかし、まず、そのロジックをスクリプトファイルに配置する必要なく、設定された環境を使用して一時コマンドを実行できるようにしたいと思います。例えば、

bin/production_env.sh psql --username "$DB_USER" --command 'select version()'

もちろん、問題は、DB_USER正しい変数が使用可能DB_USERになる前に、現在のシェルで変数が拡張されることです。

サブシェルの変数拡張を延期してこのような一時コマンドを実行する便利な方法はありますか?それとも、一時コマンドをスクリプトに入れるのが最も簡単な方法ですか?

答え1

最後の行にこれを使用evalし、親シェルがそれを食べないことを確認してください$

#!/bin/bash
export FOO=bar
export BAR=baz
eval "$@"

次のように実行します。

wouter@gangtai:~$ ./foo.sh echo '$BAR'
baz

詳細についてはを参照してくださいhelp eval

答え2

テストでproduction_env.sh引数を使用せずに(または特殊な単一引数(例:)-i)、1行を読み(-e編集用の入力を許可)実行できます。たとえば、最後の行を次のように変更します。

if [ $# = 0 -a -t 0 ]
then read -p 'prod> ' -e cmd
     bash -c "$cmd"
else "$@"
fi

関連情報