我工作的情况是我有多个项目,每个项目都有很多脚本,这些脚本使用设置为特定于该项目的值的环境变量。
我想要做的是为每个项目使用一个单独的tmux会话,并设置变量,以便为该会话中的所有窗口设置它们。
我尝试使用set-environment选项,该选项使用-g选项,但随后为连接到该服务器的所有会话设置变量。
如果没有-g选项,我在使用show-environment时会看到它的设置,但是无法访问shell中的变量。
有没有人想出办法解决这个问题?
使用tmux 1.8和tcsh
答案 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
环境中。
bar
(或~/.profile
)中添加以下内容:~/.bashrc
# 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。
tmux
时,我希望它为该会话加载特定环境。tmux
会话,并且每个窗口调用都应加载该环境。 (就像第一次会话一样)后续会话不应干扰之前的会话。那么如何将 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"
default-command
,因为第一个窗口调用使用全局选项。default-command
。这将覆盖此会话中后续窗口调用的全局 default-command
。/path/to/startscript
替换为环境变量,该环境变量根据您要为 shell 运行的脚本设置。default-command
。但这对其他会话来说不是问题,因为会话 default-command
覆盖了全局 default-command
。请参阅额外学分:1 和 2。default-command
将被设置为创建新窗口时最后设置它的人。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
选项允许您执行的操作。