如何导出函数,来自 tmux.conf
How to export a function, from tmux.conf
我为 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
文件中执行。我已经通过在 tmux.conf
:
中这样做来修改 $PROMPT_COMMAND
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
问题:
我如何从 tmux.conf 文件 导出函数(在另一个文件中声明)并使该函数对环境可用?
如果有帮助,可以在 github
上找到当前代码
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.
您可能想在 tmux-gitbar.conf 中使用 set-environment -g PROMPT_COMMAND update_gitbar
作为指令,它将源自 .tmux.conf 通过 source /path/to/tmux-gitbar.conf
编辑:
忘了说 update_gitbar
应该是 PATH
.
中某处的可执行文件
P.S.
很酷的插件! :-)
试图通过运行-shell解决它是徒劳的。根据定义,任何使用 运行-shell 的 运行 都在 sub-shell/child 进程中,并且不会影响 tmux 的环境。
外部 shell 脚本
老实说,我强烈建议您使用外部 shell 脚本,而不是函数。除其他外,这将允许您对 update_gitbar
进行更改,这些更改会在任何地方立即生效。当然,它的效率稍低,但我认为您不太可能注意到其中的区别。把它扔进 ~/bin
,然后让 PROMPT_COMMAND
变成 "$HOME/bin/update_gitbar; $PROMPT_COMMAND"
.
但是,如果您必须坚持使用 shell 函数——我必须指出,这只是 bash- 的一个特性,并且也是去年 主要 安全漏洞的来源("ShellShock";注意:不是使用 功能,只是它的实际 存在,以及非常糟糕的实现,此后已在较新版本中修复),我可以提供两种解决方案。
在 运行ning tmux
之前导出
第一种也是最简单的方法就是确保在启动 tmux 会话的环境中进行导出,而不是在它之后或之中。如果你启动 tmux 而不是 shell 脚本,比如说,你会这样做:
export -f update_gitbar
tmux
作为该启动的一部分,您可能还想放置 update_gitbar
的定义和您的 PROMPT_COMMAND
设置。请注意,一旦 tmux 启动,您将无法更改 update_gitbar
并将其传播到任何使用它的地方——这就是为什么我建议使用 shell 脚本。但是,您仍然可以使用下面描述的方法修改 new shells(例如,在新的 tmux 窗格中)的含义。
不可移植的变量导出
最后一种方法,也是最难和最不便携的,是使用 tmux 的 setenv
,或 .tmux.conf
中相同的 VAR=value
语法。 Bash 仅通过使用具有特殊格式的普通导出变量来实现其独特的 "export function" 功能。
由于修复了上述 "ShellShock" 安全漏洞,bash 的不同发行版和版本之间该格式的确切性质不同,因此 (a) 您在一个环境中所做的可能不能在另一个中工作,并且 (b) 我不能告诉你确切的导出变量名,你需要做你想做的事。
为了找出您需要的变量格式,在具有 update_gitbar
、运行:
的常规 shell 中
env | sed -n '/^[^=]*update_gitbar/,/^}/p' |
perl -ne 'chomp; $a .= $a? "; $_" : $_; END{$a=~s/=(.*)/='\'''\''/; 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/=(.*)/='\'''\''/; print "$a\n"}'
>>>> BASH_FUNC_hello%%='() { echo hi\!; }'
(>>>>
前缀的行是输出的,不是示例中脚本的一部分。)
虽然我必须指出已经有可行的答案,但我想再提一个解决你问题的方法。
有一个 mod 向 tmux 添加完整的脚本:http://ershov.github.io/tmux/(我是作者)。
它不仅允许创建新命令:
proc update_gitbar {} { run-shell "source ~/.tmux-gitbar/tmux-gitbar.sh" }
(针对您的情况)
...但也允许您将多个操作绑定到 'mode' 击键。
它也可用于用该语言编写完整的插件,根本不需要生成 shell。
我为 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
文件中执行。我已经通过在 tmux.conf
:
$PROMPT_COMMAND
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
问题:
我如何从 tmux.conf 文件 导出函数(在另一个文件中声明)并使该函数对环境可用?
如果有帮助,可以在 github
上找到当前代码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.
您可能想在 tmux-gitbar.conf 中使用 set-environment -g PROMPT_COMMAND update_gitbar
作为指令,它将源自 .tmux.conf 通过 source /path/to/tmux-gitbar.conf
编辑:
忘了说 update_gitbar
应该是 PATH
.
P.S.
很酷的插件! :-)
试图通过运行-shell解决它是徒劳的。根据定义,任何使用 运行-shell 的 运行 都在 sub-shell/child 进程中,并且不会影响 tmux 的环境。
外部 shell 脚本
老实说,我强烈建议您使用外部 shell 脚本,而不是函数。除其他外,这将允许您对 update_gitbar
进行更改,这些更改会在任何地方立即生效。当然,它的效率稍低,但我认为您不太可能注意到其中的区别。把它扔进 ~/bin
,然后让 PROMPT_COMMAND
变成 "$HOME/bin/update_gitbar; $PROMPT_COMMAND"
.
但是,如果您必须坚持使用 shell 函数——我必须指出,这只是 bash- 的一个特性,并且也是去年 主要 安全漏洞的来源("ShellShock";注意:不是使用 功能,只是它的实际 存在,以及非常糟糕的实现,此后已在较新版本中修复),我可以提供两种解决方案。
在 运行ning tmux
之前导出第一种也是最简单的方法就是确保在启动 tmux 会话的环境中进行导出,而不是在它之后或之中。如果你启动 tmux 而不是 shell 脚本,比如说,你会这样做:
export -f update_gitbar
tmux
作为该启动的一部分,您可能还想放置 update_gitbar
的定义和您的 PROMPT_COMMAND
设置。请注意,一旦 tmux 启动,您将无法更改 update_gitbar
并将其传播到任何使用它的地方——这就是为什么我建议使用 shell 脚本。但是,您仍然可以使用下面描述的方法修改 new shells(例如,在新的 tmux 窗格中)的含义。
不可移植的变量导出
最后一种方法,也是最难和最不便携的,是使用 tmux 的 setenv
,或 .tmux.conf
中相同的 VAR=value
语法。 Bash 仅通过使用具有特殊格式的普通导出变量来实现其独特的 "export function" 功能。
由于修复了上述 "ShellShock" 安全漏洞,bash 的不同发行版和版本之间该格式的确切性质不同,因此 (a) 您在一个环境中所做的可能不能在另一个中工作,并且 (b) 我不能告诉你确切的导出变量名,你需要做你想做的事。
为了找出您需要的变量格式,在具有 update_gitbar
、运行:
env | sed -n '/^[^=]*update_gitbar/,/^}/p' |
perl -ne 'chomp; $a .= $a? "; $_" : $_; END{$a=~s/=(.*)/='\'''\''/; 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/=(.*)/='\'''\''/; print "$a\n"}'
>>>> BASH_FUNC_hello%%='() { echo hi\!; }'
(>>>>
前缀的行是输出的,不是示例中脚本的一部分。)
虽然我必须指出已经有可行的答案,但我想再提一个解决你问题的方法。
有一个 mod 向 tmux 添加完整的脚本:http://ershov.github.io/tmux/(我是作者)。
它不仅允许创建新命令:
proc update_gitbar {} { run-shell "source ~/.tmux-gitbar/tmux-gitbar.sh" }
(针对您的情况)
...但也允许您将多个操作绑定到 'mode' 击键。
它也可用于用该语言编写完整的插件,根本不需要生成 shell。