为 bundle exec

问题描述

我见过两种在执行 bundle exec 时指定环境变量的不同方法。哪个在 Linux 上是正确的?也许两者都有?我正在寻找一般性的答案,我知道在这种特殊情况下(更新 Redmine)指定 RAILS_ENV 甚至可能是不必要的。

bundle exec rake db:migrate RAILS_ENV=production
RAILS_ENV=production bundle exec rake db:migrate

解决方法

这两个选项都可以为 rake 任务定义环境变量。但是,对于其他可执行文件(例如 rails 可执行文件),仅支持在可执行文件之前定义变量的变体。

这里发生的事情是,当您在开始时指定环境变量时,您的 shell(bash、zsh、...)为新启动的进程设置了这些环境变量。这可以用于任何进程。进程还继承了先前在 shell 中定义的环境变量。因此,第三种选择可能是在您的 shell 中运行它:

export RAILS_ENV=production
bundle exec rake db:migrate

现在,如果您将变量指定为 rake 可执行文件的参数,shell 不会影响、读取或写入这些变量。相反,rake 本身会检查其给定的进程参数,并在将控制权交给实际的 rake 任务(在本例中为 db:migrate)之前为其自己的进程设置环境变量。

为了让您为各种可执行文件定义环境变量的能力更加一致,我个人倾向于坚持在 shell 中设置环境变量的选项,而不是使用 rake 功能来解析其参数。

最后,关于您所说的 RAILS_ENV 环境变量在这里可能不是必需的:这可能不是真的。 Rails 应用程序(例如 Redmine)根据加载的环境定义不同的行为,包括它们连接的数据库(在 config/database.yml 文件中定义)、其他设置(在 config/configuration.yml 中为 Redmine 定义)和内部参数例如记录详细程度和异常处理。因此,如果未指定任何内容,您很可能希望始终在任何地方使用 RAILS_ENV=production,因为 Rails(和 Redmine)默认为开发环境。