Capistrano:我可以为整个上限会话设置一个环境变量吗?

时间:2011-09-29 19:41:24

标签: environment-variables capistrano

我有一台安装了标准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 ...

并且只要另一个shell在传递给env的可执行文件中旋转,它们就会丢失。就像你使用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 export命令,因为它们也丢失了--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选项(并结合其他方法),但也没有运气。

那么 - 这样做的正确方法是什么?这似乎是一个基本的任务,应该有一个非常简单的方法来实现它,但我没有想法。任何人吗?

提前致谢!

5 个答案:

答案 0 :(得分:49)

我有完全相同的问题,但我认为这个解决方案更好:

set :default_environment, { 
  'env_var1' => 'value1',
  'env_var2' => 'value2'
}

这对我来说就像一个魅力。

答案 1 :(得分:10)

如果需要在除PATH之外的远程主机上设置变量,则出于安全原因,您应该知道sshd默认情况下仅允许某些/etc/profile~/.bashrc环境变量。正如Lou所说,您可以cap shell使用cap> printenv命令,也可以在一个命令中执行cap COMMAND=printenv invoke

如果你正常ssh到远程shell时看到变量,但你没有在cap printenv命令中看到它,这里有一个解决方案:

  1. 在远程服务器的PermitUserEnvironment yes文件中设置/etc/ssh/sshd_config,然后重新启动sshd
  2. 编辑您正在搜索的远程用户的~/.ssh/environment文件,并将您的变量放在VARIABLE=value
  3. 现在,当您执行cap COMMAND=printenv invoke

    时,这些内容会显示出来

答案 2 :(得分:5)

我认为你实际上有两个问题:

1)您想要更改远程主机上的PATH。

更改/设置远程主机上.bashrc中的路径并运行cap> printenv,如果路径正确,请转到#2,否则尝试将export BASH_ENV=~/.bashrc添加到/etc/profile 1}}(小心,然后将为所有用户的所有非交互式shell运行〜/ .bashrc)

2)你希望sudo保持你的PATH

在远程主机上运行visudo并添加:

Defaults        exempt_group = "<your_user>"

答案 3 :(得分:3)

我需要为特定任务设置环境变量才能工作。 “run”命令允许您传递包含以下内容的选项:env:

run "cmd", :env => { 'name' => 'value' }

在我的情况下,我想将环境变量添加到我没有编写的任务中,所以我使用了default_run_options,它被run的所有调用使用。我把它添加到我的Capfile顶部:

default_run_options[:env] = { 'name' => 'value' }

答案 4 :(得分:0)

我尝试使用@ brian-deterling的技术失败了,这是其他人讨论过这个问题时常用的...也许我做错了,但同时我发现了dotenv-rails宝石,它非常适合从我的项目根目录中加载.env文件中的值。

Github repo上的说明非常简单。我将Dotenv.load添加到了config/application.rb