【问题标题】:TMUX setting environment variables for sessionsTMUX 为会话设置环境变量
【发布时间】:2013-12-20 10:41:58
【问题描述】:

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

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

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

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

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

使用 tmux 1.8 和 tcsh

【问题讨论】:

    标签: tmux


    【解决方案1】:

    我想出了一个办法。我正在使用 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
    

    【讨论】:

    • setenv 的目的是什么,确切地说,如果通过该命令设置的环境变量不能被 echo $foo 之类的东西访问?
    • 当你创建一个会话时,它会自动创建窗口 0,它会触发一个 shell。所以,对于那个 shell,setenv 不起作用,你必须发送密钥。但是当你创建一个新窗口时,就像使用拆分窗口一样,新窗口会从 setenv 获取环境。该示例显示,无论是通过 export 还是通过 setenv 显式设置,两个窗口都有环境。
    • 为什么它不适用于多个setenv:sentenv FOO $BAR \; \ setenv FIZZ $BUZZ
    【解决方案2】:

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

    bash> tmux show-environment
    

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

    bash> tmux show-environment variable_name
              variable_name=value
    

    要获得该值,您可以使用一些“sed”魔法或对单个变量使用“导出”,或者您甚至可以将整个环境“导出”到您的 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 参数。

    【讨论】:

      【解决方案3】:

      我做了一个简单的

      export MY_VAR="some value"
      

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

      【讨论】:

      • 每次启动 tmux 时都这样做怎么样?
      • @holms 为此你可以alias tmux='SOME_ENV_VAR=somevalue tmux'
      • 这在您创建第一个会话并且tmux 启动其服务器进程时起作用。但是,如果您启动第二个会话,它将连接到同一个 tmux 服务器,因此它将获取您第一次启动服务器时设置的环境变量,而不是最近的。
      • 它影响连接到服务器的所有会话。所有新创建的窗口也会受到影响...
      • @ghchoi 但如果您已经连接到该服务器的其他 tmux-sessions 已经在运行,则在打开另一个会话之前导出变量不起作用
      【解决方案4】:

      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 选项允许您执行的操作。

      【讨论】:

        【解决方案5】:

        示例

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

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

        但是,如果我需要为Session_1 设置foo 环境,为Session_2 设置bar 环境,则VIRTUAL_ENV 变量在创建Session_2 后全局设置为bar,因此任何新打开的选项卡在 Session_1 中错误地结束在 bar 环境中。

        解决方案

        original HOWTO (commit)。

        1. 在您的~/.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
        
        1. 为目标会话设置VIRTUAL_ENV 变量:
        tmux setenv -t ${SESSION_NAME} 'VIRTUAL_ENV' /path/to/virtualenv/
        

        【讨论】:

          【解决方案6】:

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

          使用 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。

          Shell环境A:tmux -L environA

          Shell环境B:tmux -L environB

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

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

          【讨论】:

          • 这个答案缺少我需要的关键点:我有多个会话,并使用唯一的 -L <name> args 将它们隔离开来解决了我的问题。
          【解决方案7】:

          为当前 session 设置它非常简单:Ctr-b: 打开 tmux 命令提示符和输入setenv FOO foo。这不适用于现有的windows——但你可以使用export $(tmux show-env FOO)

          对于新会话,此模式可能有用:

          1. tmux new -s session
          2. Ctr-b : set-env FOO foo -- 为会话设置FOO=foo
          3. Ctr-b c -- 创建新的第二个窗口(@98​​7654326@ 在这里设置)
          4. Ctr-b l -- 转到旧的,第一个窗口
          5. exit第一个窗口
          6. 现在所有窗口都有FOO=foo

          使用 Tmux 1.8 测试。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-08-16
            • 1970-01-01
            • 2021-03-07
            • 2021-06-14
            • 2014-04-03
            • 2020-08-13
            • 2015-09-03
            • 2013-01-29
            相关资源
            最近更新 更多