TMUX设置会话的环境变量

时间:2013-12-20 10:41:58

标签: tmux

我工作的情况是我有多个项目,每个项目都有很多脚本,这些脚本使用设置为特定于该项目的值的环境变量。

我想要做的是为每个项目使用一个单独的tmux会话,并设置变量,以便为该会话中的所有窗口设置它们。

我尝试使用set-environment选项,该选项使用-g选项,但随后为连接到该服务器的所有会话设置变量。

如果没有-g选项,我在使用show-environment时会看到它的设置,但是无法访问shell中的变量。

有没有人想出办法解决这个问题?

使用tmux 1.8和tcsh

6 个答案:

答案 0 :(得分:5)

您可以在会话中使用以下命令访问每个会话的tmux(本地)环境变量:

bash> tmux show-environment

如果添加-g参数,则会获得所有会话的环境,即全局环境。本地环境与全球环境不同。上一个命令打印整个本地环境,但您也可以只查看一个变量:

bash> tmux show-environment variable_name
          variable_name=value

要获得该值,您可以在单个变量上使用某些“sed”魔法或使用“export”,或者甚至可以将整个环境“导出”到shell中。以下是3种方法。

bash> tmux show-environment variable_name | sed "s:^.*=::"
         value

bash> eval "export $(tmux show-environment variable_name)"
bash> echo $variable_name
         value    

bash> for var in $(tmux show-environment | grep -v "^-"); do eval "export $var"; done;
bash> echo $variable_name
         value    

如果需要,您可以在show-environment命令后添加-g参数,以便访问全局环境。

答案 1 :(得分:4)

我做了一个简单的

export MY_VAR="some value"

在我启动tmux会话之前,这使我可以从该会话中的所有窗口访问MY_VAR

答案 2 :(得分:3)

我找到了一种方法来做到这一点。我使用的是tmux 2.5。

<强>背景

在tmux手册页中,它指出有两组环境变量:全局和每个会话。当您创建新的tmux会话时,它会将两个组合并在一起,并成为会话中可用的环境变量集。如果环境变量被添加到全局组,则看起来它们在所有打开的会话之间共享。您想将它们添加到每个会话组。

执行此操作

步骤1:创建tmux会话。

tmux new-session -s one

步骤2:将环境变量添加到每个会话组。

tmux setenv FOO foo-one

这会将环境变量添加到每个会话的环境变量集中。如果您输入tmux showenv,则会在输出中看到它。但是,它不在当前会话的环境中。打字echo $FOO不会给你任何东西。可能有更好的方法,但我发现最简单的方法是手动导出它:

export FOO='foo-one'

第3步:创建新窗口/窗格

现在,每次在当前会话中创建新窗口或窗格时,tmux都会从每个会话组中获取FOO环境变量。

自动化

我使用bash脚本自动创建利用这些环境变量的tmux会话。以下是我如何自动执行上述操作的示例:

#!/bin/bash
BAR='foo-one'
tmux new-session -s one \; \
  setenv FOO $BAR \; \
  send-keys -t 0 "export FOO="$BAR C-m \; \
  split-window -v \; \
  send-keys -t 0 'echo $FOO' C-m \; \
  send-keys -t 1 'echo $FOO' C-m

答案 3 :(得分:2)

示例

就我而言,我正在bash脚本中为每个项目启动一个tmux会话,我需要为该会话激活一个相关的虚拟环境,包括任何新打开的选项卡。为此,我将以下虚拟环境激活代码添加到~/.bashrc

if [ -n "$VIRTUAL_ENV" ]; then
    source $VIRTUAL_ENV/bin/activate;
fi

但是,如果我需要为foo设置Session_1环境并且为bar设置Session_2环境,则VIRTUAL_ENV变量将全局设置为{{1} }创建bar之后,因此Session_2中新打开的标签页都会错误地出现在Session_1环境中。

解决方案

original HOWTOcommit)。

  1. 在您的bar(或~/.profile)中添加以下内容:
~/.bashrc
  1. 为目标会话设置# For Tmux VirtualEnv support tmux_get_var(){ local key=$1 [[ -n "$TMUX" ]] && tmux showenv | awk -F= -v key="$key" '$1==key {print $2}' } # activate the virtual environment if it is declared venv=$(tmux_get_var "VIRTUAL_ENV") if [ -n "$venv" ]; then source $venv/bin/activate; fi 变量:
VIRTUAL_ENV

答案 4 :(得分:0)

我的处理方式略有不同,假设我为每个环境都有单独的初始化脚本。

使用 tmux v3.0a。

规范:

  1. 当我调用 tmux 时,我希望它为该会话加载特定环境。
  2. 对于 tmux 会话中的每个窗口,我希望复制相同的环境会话。
  3. 我还希望能够调用具有不同环境的后续 tmux 会话,并且每个窗口调用都应加载该环境。 (就像第一次会话一样)后续会话不应干扰之前的会话。
  4. 我有 shell 脚本来初始化我的每个环境。

那么如何将 shell 脚本与会话相关联并让所有窗口调用都使用该 shell 脚本?

更简单的解决方案:

在这里找到了一个更简单的解决方案:How to start two tmux sessions with different environments?

使用我的原始解决方案时,我遇到了 tmux 全局环境的问题。当我运行多个会话时,首先运行的会话设置全局环境。然后我需要在运行新会话之前关闭其他 tmux 会话。

更好的解决方案是为每个环境设置单独的 tmux 服务器。

使用 -L 标志从已经定义了所需环境的 shell 中进行 tmux。

外壳环境 A:tmux -L environA

外壳环境 B:tmux -L environB

以您想要的任何方式命名您的环境。为每个环境设置一些别名?或者您可以测试环境变量以确定要使用的 tmux 服务器。每个 tmux 命名服务器将保持其环境独立。

那么就不用像我原来的方案中描述的那样设置bash启动文件等了。


可以忽略:原始解决方案:

我可以使用 default-command 来定义我想为任何会话创建和会话内后续窗口创建运行的脚本。

tmux set-option -g default-command "/usr/bin/bash --rcfile /path/to/startscript" \; \
new-session \; \
set-option  default-command "/usr/bin/bash --rcfile /path/to/startscript"

解决方案描述:

  1. 需要设置全局 default-command,因为第一个窗口调用使用全局选项。
  2. 开始会议。
  3. 现在设置会话 default-command。这将覆盖此会话中后续窗口调用的全局 default-command
  4. 使用此解决方案,您可以将 /path/to/startscript 替换为环境变量,该环境变量根据您要为 shell 运行的脚本设置。
  5. 每次创建会话时,都会修改全局 default-command。但这对其他会话来说不是问题,因为会话 default-command 覆盖了全局 default-command。请参阅额外学分:1 和 2。

额外的功劳:

  1. 尝试删除命令的最后 2 行并打开多个 tmux 会话,您将看到全局 default-command 将被设置为创建新窗口时最后设置它的人。
  2. 尝试仅删除第一行,您将看到初始会话未正确加载。
  3. 您可以使用 new-session 命名和标志来定义会话实例化行为。我更喜欢每次调用时都有一个新的会话。

答案 5 :(得分:0)

tmux 3.2 版将支持 -e 命令的 new-session 选项,用于直接更改本地环境。

与此同时,您可以使用它来运行具有可用且最新的特定环境的新 tmux 会话(或提到的其他解决方案之一):

tmux new-session 'export MY_VAR=value; exec bash'

tmux 的问题在于,当您第一次运行它时,会创建 tmux 服务器,并且它继承了创建时可用的环境。这称为全局环境。当您再次运行 tmux 并创建新会话时,tmux 服务器仍保留其环境副本。但是这个副本是服务器在创建时了解到的“旧”环境,即全局环境。

关于适用于 tmux 环境的 tmux 命令:

  • set update-environment MY_VAR:这将告诉 tmux 从全局环境中获取 MY_VAR 变量并使其成为会话环境,即本地环境(由 show-environment 命令列出)。然后,会话将能够在不影响全局环境的情况下更改此变量的值。
  • set-environment MY_VAR value:这将在会话的本地环境中创建(或更改)一个变量。
  • set-environment -g MY_VAR value:这将在全局环境中创建(或更改)一个变量。

另外,请注意,当您运行 tmux 并且 tmux 调用 bash(或其他 shell)时,bash 将拥有服务器(全局)环境的副本。即使您在调用 tmux 之前更改了环境变量,创建新会话也不会注意到这些更改。如果您在 conf 文件中添加 tmux 命令并运行 tmux 例如使用 tmux source-file tmux-session.conf,您在 conf 中提到的任何变量都将在 tmux 服务器知道的全局环境的上下文中进行评估,而不是在您运行 tmux 命令的上下文中。因此,为了让新会话看到变量的新值,您必须以将 env 变量的新值直接传递给它的方式调用 tmux。这就是这里的解决方案试图做的。这也是新的 -e 选项允许您执行的操作。