如何从tmux.conf导出函数

时间:2016-02-20 10:52:18

标签: git bash prompt tmux

我为tmux tmux-gitbar写了一个插件。它显示了有关tmux状态栏中当前目录的Git状态的一些信息。每次用户运行命令时,状态栏必须更新,为此,我添加了一个从$PROMPT_COMMAND变量调用的函数。

我现在在做什么:

文件 .bashrc

source ~/.tmux-gitbar/tmux-gitbar.sh;
文件 tmux-gitbar.sh

update_gitbar() {
    #
    # update tmux status bar
    #
}
PROMPT_COMMAND="update_gitbar; $PROMPT_COMMAND"


我希望在不向.bashrc 添加行的情况下获得相同的结果。所有内容都应在tmux.conf文件中执行。我已经设法通过在$PROMPT_COMMAND中执行此操作来修改tmux.conf

PROMPT_COMMAND="update_gitbar; $PROMPT_COMMAND"

现在我的问题是将update_gitbar功能导出到环境中

我尝试了各种方法来获取脚本,但没有运气:

run-shell "source ~/.tmux-gitbar/tmux-gitbar.sh"
run-shell "eval $(~/.tmux-gitbar/tmux-gitbar.sh)"
run-shell "eval $(cat ~/.tmux-gitbar/tmux-gitbar.sh)"

我总是得到:

update_gitbar: command not found

问题:

如何从 导出一个函数(在另一个文件中声明)并使该函数可用于环境?

如果可以提供帮助,则可以在github

上找到当前代码

3 个答案:

答案 0 :(得分:2)

tmux set-environment看起来很有希望并可能对您有所帮助。 让我引用man tmux

中的相关部分
set-environment [-gru] [-t target-session] name [value]
              (alias: setenv)
        Set or unset an environment variable.
        If -g is used, the change is made in the global environment; 
        otherwise, it is applied to the session environment for target-session.
        The -u flag unsets a variable.
        -r indicates the variable is to be removed from the environment before starting a new process.

您可能希望使用set-environment -g PROMPT_COMMAND update_gitbar作为 tmux-gitbar.conf 中的指令,该指令将来自 .tmux.conf ,通过{{1 }}

修改 忘了提及source /path/to/tmux-gitbar.conf应该是update_gitbar中的某个可执行文件。

P.S。

酷插件! : - )

答案 1 :(得分:2)

尝试通过run-shell解决它是徒劳的。根据定义,使用run-shell运行的任何东西都在子shell /子进程中,并且不能影响tmux的环境。

外壳脚本

老实说,我强烈建议您使用外部shell脚本而不是函数。除此之外,这将允许您对update_gitbar进行更改,以便在任何地方立即生效。当然效率稍差,但我不认为你可能会注意到这种差异。只需将其放入~/bin,然后将PROMPT_COMMAND设为"$HOME/bin/update_gitbar; $PROMPT_COMMAND"

但是,如果你必须坚持使用shell函数 - 我必须指出,它只是一个bash- 功能,并且也是主要安全漏洞的来源去年(" ShellShock&#34 ;;注意:不是使用的功能,只是它的实际存在,以及非常破碎的实现,已经修复了在较新版本中,我可以提供两种解决方案。

在运行tmux之前导出

第一种也是最简单的方法是确保在启动tmux会话的环境中进行导出,而不是在其之后或之内。如果您启动tmux而不是shell脚本,比如说,您只需执行:

export -f update_gitbar
tmux

作为该创业公司的一部分,您可能还想要定义update_gitbarPROMPT_COMMAND设置。请注意,一旦tmux启动,您将无法更改update_gitbar并将其传播到所使用的所有位置 - 这就是我推荐使用shell脚本的原因。但是,您仍然可以使用下面描述的方法修改 new shell(在新的tmux窗格中)的含义。

Unportable variable exports

最后一种最难且最不便携的方法是在setenv中使用tmux的VAR=value或相同的.tmux.conf语法。 Bash实现了其独特的出口功能"只需使用具有特殊格式的普通导出变量即可实现。

由于修复了" ShellShock" bash的不同发行版和版本之间格式的确切性质不同。上面提到的安全漏洞,所以(a)你在一个环境中所做的事情可能在另一个环境中不起作用,(b)我无法告诉你你需要做的所需的确切导出变量名称。

为了找出您需要的变量格式,在具有update_gitbar的常规shell中运行:

env | sed -n '/^[^=]*update_gitbar/,/^}/p' |
perl -ne 'chomp; $a .= $a? "; $_" : $_; END{$a=~s/=(.*)/='\''$1'\''/; print "$a\n"}'

这个复杂的命令只是在环境中查找导出的shell函数并打印其值。 Bash包含导出变量值的换行符,因此它会继续从环境中获取,直到它看到一行单独使用右括号。然后它用分号替换所有这些换行符,以便您可以将它全部放在一行上。最后,它替换单引号内变量的值,以避免字符的特殊含义。如果由于某种原因无法从该命令获取可用值,则可以自己执行该过程。

对我来说,下面的示例说明了我的特定发行版和bash版的格式(在我将update_gitbar更改为hello的命令中的注意事项)。正如我所提到的,您的结果可能会有所不同,因此请务必在您的系统上进行试用。

获得所需的变量后,只需将其插入.tmux.conf,或使用setenv版本。

hello() {
    echo hi;
}
export -f hello
hello
>>>> hi
env | sed -n '/^[^=]*hello/,/^}/p' |
perl -ne 'chomp; $a .= $a? "; $_" : $_; END{$a=~s/=(.*)/='\''$1'\''/; print "$a\n"}'
>>>> BASH_FUNC_hello%%='() {  echo hi\!; }'

(输出>>>> - 前缀行,而不是示例中脚本的一部分。)

答案 2 :(得分:1)

虽然我必须指出已有可行的答案,但我想再提一个解决问题的方法。

有一个mod为tmux添加了完整的脚本:http://ershov.github.io/tmux/(我是作者)。

它不仅允许创建新命令:

proc update_gitbar {} { run-shell "source ~/.tmux-gitbar/tmux-gitbar.sh" }

(适合您的情况)

...但也允许您将多个动作绑定到“模式”按键。

它也可以用这种语言编写完整的插件,而根本不需要生成shell。