Отложить переменное расширение до подоболочки

В моем сервисе широко используются переменные среды для конфигурации (в основном потому, что их очень легко внедрить в контейнер Docker).

У меня также есть некоторые сценарии обслуживания, которые я могу запустить против своей производственной среды. Но так как я действительно не хочу, чтобы моя среда оболочки настроена для работы с prod по умолчанию, вместо этого у меня есть вспомогательный скрипт, который настраивает среду, а затем вызывает мой сценарий обслуживания. Сценарий помощника в настоящее время выглядит примерно так:

#!/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 . Все это отлично работает.

Одним из моих сценариев обслуживания является 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 будет доступна правильная переменная DB_USER .

Есть ли удобный способ запуска таких специальных команд, откладывающих расширение переменных до подоболочки? Или проще всего использовать мои специальные команды в сценарии?

2 Solutions collect form web for “Отложить переменное расширение до подоболочки”

Используйте eval в своей последней строке и убедитесь, что родительская оболочка не ест $ :

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

выполните так:

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

Для получения дополнительной информации см. help eval .

Вы можете получить свой файл production_env.sh для тестирования без аргументов (или какого-либо отдельного аргумента типа -i ), а затем прочитать одну строку (с -e для редактирования ввода) и выполнить ее. Например, измените свою последнюю строку на:

 if [ $# = 0 -a -t 0 ] then read -p 'prod> ' -e cmd bash -c "$cmd" else "$@" fi 
Linux и Unix - лучшая ОС в мире.