(免责声明:我完全知道,我下面描述的问题有解决方案,涉及编写和调用与正在运行的tmux服务器进行交互的shell脚本,或者在启动tmux服务器之前设置必要的环境变量。我特别是发布此问题,以查看是否有可能无需使用此类脚本来解决此问题。)
在我的.tmux.conf
文件中,我试图根据调用tmux之前是否已设置环境变量VALUE
来将局部变量FOO
设置为不同的值。然后,我想在其他tmux命令中使用VALUE
。不幸的是,我无法正确设置VALUE
或在设置之后访问它。
根据我在手册页和其他包含示例tmux代码的常见问题解答帖子中所发现的内容,有几种方法可以实现上述目的。
我首先尝试使用if-shell
命令。我尝试同时使用带有和不带有-b
标志的命令;两种情况下的结果都是相同的。
从示例中可以看出,我可以使用语法VALUE=bar
分配变量。鉴于此,这是我的配置的一个最小示例:
if-shell '[ -z "$FOO" ]' \
'VALUE=bar' \
'VALUE=baz'
set-environment -g RESULT $VALUE
终端会议:
$ echo $FOO
$ tmux
[detached (from session 0)]
$ tmux showenv -g VALUE
VALUE=bar
$ tmux showenv -g RESULT
RESULT=
$ killall tmux
$ export FOO=foo
$ echo $FOO
foo
$ tmux
[detached (from session 0)]
$ tmux showenv -g VALUE
VALUE=baz
$ tmux showenv -g RESULT
RESULT=
因此,尽管VALUE
似乎已正确设置,但RESULT
似乎无法访问VALUE
。
该手册页还提到可以使用%if
语句有条件地执行命令。使用这种格式,我尝试了以下配置:
%if #{#(if [ -z "$FOO" ]; then echo 1; else echo 0)}
VALUE=bar
%else
VALUE=baz
%endif
set-environment -g RESULT $VALUE
对于%if
语句中的表达式,我尝试了几种变体,例如
#{#([ -z "$FOO" ])}
(我相信这不应该起作用,因为该命令不会产生任何输出,但是值得一试。)#{==:#(if [-z "$FOO" ]; then echo 1; else echo 0),1}
(以防万一明确的比较可行)即使有这些变化,无论是否设置了FOO
,我都会得到以下信息:
$ tmux
[detached (from session 0)]
$ tmux showenv -g VALUE
VALUE=baz
$ tmux showenv -g RESULT
RESULT=baz
因此,尽管可以访问VALUE
,但始终是baz
。
不幸的是,我找不到关于条件语句中使用的格式的有用示例。该手册页描述了如何访问tmux变量和一些格式提示。但是,关于访问环境变量,我所能找到的只是一种使用shell命令的方法:
此外,可以使用
#()
插入shell命令输出的第一行。例如,#(uptime)
将插入系统的正常运行时间。在构造格式时,tmux不会等待#()
命令完成;相反,将使用先前运行同一命令的结果,如果先前未运行过该命令,则使用占位符。
我不确定这是否意味着我需要两次在#()
中调用命令以避免使用占位符值,这可能对我来说是一个错误。
我也找不到一种方法来轻松打印#{}
命令的结果以调试语句的这一部分。
尽管我希望获得任何可以帮助我解决该问题的信息,但对我而言最紧迫的问题是:
VALUE
的设置正确,但是尝试1中的RESULT
无法访问?VALUE
?答案 0 :(得分:2)
tmux运行配置的方式是将配置文件解析为一组命令,然后执行它们(存在命令队列,因此将配置文件解析并附加到队列中,然后从队列中执行) 。因此,有不同的解析和执行步骤。
尝试1遇到的问题是if-shell在执行时运行,但是$ VALUE扩展在解析时发生。解析set-environment命令时未设置VALUE。
在尝试2中,未在%if内部处理#(),因此将无法正常工作。但是,您可以直接以格式使用变量(如果已设置)。 %if在解析时发生。
因此,您需要确保分配和扩展按正确的顺序进行。您有两种选择。
您可以使tmux在命令执行时而不是解析时扩展变量。您可以通过将setenv包装在run-shell中来完成此操作,例如:
if-shell '[ -z "$FOO" ]' \
'VALUE=bar' \
'VALUE=baz'
run 'tmux setenv -g RESULT $VALUE'
或者您可以像在尝试2中一样尝试在解析时进行分配,但是您不能使用#()-您需要使用一种格式:
%if #{==:#{FOO},}
VALUE=bar
%else
VALUE=baz
%endif
setenv -g RESULT $VALUE
(请注意,配置文件中的X = Y与setenv -g X = Y等效,除了它在解析而不是执行时发生-都设置了全局环境。因此,您可以摆脱VALUE并执行RESULT = bar或%if中的setenv -g结果栏。)
答案 1 :(得分:0)
还可以使用display -p打印格式。在master和2.9中,您可以添加-v以查看其解析方式:
$ tmux setenv -g FOO bar
$ tmux display -pv '#{==:#{FOO},baz}'
# expanding format: #{==:#{FOO},baz}
# found #{}: ==:#{FOO},baz
# modifier 0 is ==
# expanding format: #{FOO}
# found #{}: FOO
# format 'FOO' found: bar
# replaced 'FOO' with 'bar'
# result is: bar
# expanding format: baz
# result is: baz
# compare == left is: bar
# compare == right is: baz
# replaced '==:#{FOO},baz' with '0'
# result is: 0
0