Capistrano:我可以为整个 cap 会话设置一个环境变量吗?
Posted
技术标签:
【中文标题】Capistrano:我可以为整个 cap 会话设置一个环境变量吗?【英文标题】:Capistrano: Can I set an environment variable for the whole cap session? 【发布时间】:2011-11-27 23:43:23 【问题描述】:我有一个安装了标准 Ruby 和 Ruby Enterprise 的登台服务器。由于标准 Ruby 拒绝安装关键 gem,我需要设置 $PATH 以便 ruby/gem/rake/etc.始终参考 REE 版本。由于我使用 Capistrano 部署到我们的机器上,因此我需要在 Capistrano 中进行部署。
如何设置一次环境变量,并让它在 Capistrano 会话中持续存在?
1) 在 bashrc 文件中很容易做到,但 Capistrano 不读取 bashrc 文件。
2) 我会使用 Capistrano 的
default_environment['PATH'] = 'Whatever'
但 Capistrano 使用这些环境变量,例如
env PATH=Whatever command arg ...
并且每当在传递给 env 的可执行文件中启动另一个 shell 时,它们就会丢失。就像你使用 sudo 时一样。哪一点很重要:
[holt@Michaela trunk]$ env VAR=hello ruby -e "puts ENV['VAR']"
hello
[holt@Michaela trunk]$ env VAR=hello sudo ruby -e "puts ENV['VAR']"
nil
3) 我不能使用 bash 导出命令,因为这些命令也丢失了 - Capistrano 似乎为每个命令(或类似的命令)启动了一个新的 shell,这也丢失了:
cap> export MYVAR=12
[establishing connection(s) to xxx.xxx.xxx.xxx]
cap> echo $MYVAR
** [out :: xxx.xxx.xxx.xxx]
cap>
4) 我也尝试过使用 Capistrano 的 :shell 和 :pty 选项(并与其他方法结合使用),但也没有运气。
那么 - 这样做的正确方法是什么? 这似乎是一项基本任务,应该有一个非常简单的方法来完成它,但我没有想法。有人吗?
提前致谢!
【问题讨论】:
【参考方案1】:我有完全相同的问题,但我认为这个解决方案更好:
set :default_environment,
'env_var1' => 'value1',
'env_var2' => 'value2'
这对我来说就像一个魅力。
【讨论】:
嗯,不适合我看***.com/questions/16889642/… 在 Capistrano 3 中是set :default_env, ...
愚蠢的问题,但我正在尝试同样的事情,但它不起作用。无论如何要调试它?
如何将这些放在 .env 文件中?【参考方案2】:
如果您需要在远程主机上设置 PATH 以外的变量,您应该知道出于安全原因,sshd 默认只允许某些/etc/profile
或~/.bashrc
环境变量。正如楼所说,您可以使用cap shell
并使用cap> printenv
命令,也可以在一个命令中使用cap COMMAND=printenv invoke
。
如果您在正常 ssh 进入远程 shell 时看到该变量,但在 cap printenv
命令中看不到它,这是一种解决方案:
-
在远程服务器的
/etc/ssh/sshd_config
文件中设置PermitUserEnvironment yes
,然后重启sshd
为您正在 ssh 的远程用户编辑 ~/.ssh/environment
文件,并将您的变量作为 VARIABLE=value
放在那里
现在这些应该会在您执行 cap COMMAND=printenv invoke
时出现
【讨论】:
这可能有效,但需要更改 root 权限设置。看我的回答。【参考方案3】:我认为你实际上有两个问题:
1) 您想更改远程主机上的 PATH。
更改/设置远程主机上 .bashrc 中的路径并运行 cap> printenv
,如果您的路径正确,请转到 #2,否则尝试将 export BASH_ENV=~/.bashrc
添加到您的 /etc/profile
(小心, ~/.bashrc 将为所有用户的所有非交互式 shell 运行)
2) 您希望 sudo 保留您的 PATH
在远程主机上运行 visudo
并添加:
Defaults exempt_group = "<your_user>"
【讨论】:
好电话 - 我不知道 sudo 掩盖了本地环境。看起来只是添加 -E 选项可以解决大多数情况,但 $PATH 是特殊的(reference)。我会玩这个多一点,然后回复你。干杯!【参考方案4】:我需要为特定任务设置一个环境变量才能工作。 “运行”命令允许您传递包括 :env:
在内的选项run "cmd", :env => 'name' => 'value'
就我而言,我想将环境变量添加到我没有编写的任务中,所以我使用了所有 run 调用都使用的 default_run_options。我将此添加到我的 Capfile 的顶部:
default_run_options[:env] = 'name' => 'value'
【讨论】:
我在其他地方看到过这个解决方案,但我无法让它为我工作 - 我收到一个NameError: undefined local variable or method
default_run_options' for main:Object` 错误。我把那个赋值语句放在我的Capfile
的顶部,在第一个namespace :deploy do
块之前。我可以做些什么不同的事情?
你是如何运行任务的?如果你运行 cap 任务,它应该在加载过程中定义 default_run_options 以便在它到达你的 Capfile 时可用。即使只有一行 Capfile 只是说 default_run_options[:x] = 'y' => 'z' ,我也可以运行 cap shell。【参考方案5】:
我尝试使用@brian-deterling 的技术未成功,该技术在讨论过此问题的其他人中非常常用......也许我做错了什么,但同时我找到了dotenv-rails
gem,它非常有效很好地从我的项目根目录中的.env
文件中加载值。
Github repo 上的说明非常简单。我将Dotenv.load
添加到我的config/application.rb
【讨论】:
以上是关于Capistrano:我可以为整个 cap 会话设置一个环境变量吗?的主要内容,如果未能解决你的问题,请参考以下文章