bash 如何在 .tmux.conf 中编写 if 语句来为不同的 tmux 版本设置不同的选项?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35016458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to write if statement in .tmux.conf to set different options for different tmux versions?
提问by mrt181
I have a .tmux.conf which I use on different machines with different tmux versions installed.
我有一个 .tmux.conf,我在安装了不同 tmux 版本的不同机器上使用它。
I want to set different mouse options, depending on the tmux version.
On one machine I have version 2.0
on the other 2.1
.
我想根据 tmux 版本设置不同的鼠标选项。在一台机器我有版本2.0
的其他2.1
。
I do not get his part right
我不明白他的意思
if "[[(( $(tmux -V | cut -c 6-) < 2.1 ))]]" \
"set -g mode-mouse on;" \
"set -g mouse-resize-pane on;" \
"set -g select-pane on;" \
"set -g select-window on" "set -g mouse on"
When I source the file
当我获取文件时
$ tmux source-file .tmux.conf
$ tmux source-file .tmux.conf
I get this message
我收到这条消息
.tmux.conf:12: unknown command: set -g mouse-resize-pane on
.tmux.conf:12: unknown command: set -g mouse-resize-pane on
The machine where I run it has version 2.1
so it shouldn't set the four options.
我运行它的机器有版本,2.1
所以它不应该设置四个选项。
I want to set the four options when running tmux 2.0 or less or the one option when running tmux 2.1.
我想在运行 tmux 2.0 或更低版本时设置四个选项,或者在运行 tmux 2.1 时设置一个选项。
This bash statement works
这个 bash 语句有效
$ tmux -V
tmux 2.1
$ if [[(( $(tmux -V | cut -c 6-) < 2.1 ))]];then echo $?;else echo $?;fi
1
回答by Tom Hale
Based on @ericx's answerand @thiagowfx's answerI put the following together which covers many of the listed incompatibiltiesfrom version 2.0 onwards:
根据@ericx 的回答和@thiagowfx 的回答,我将以下内容放在一起,其中涵盖了2.0 版以后列出的许多不兼容问题:
# Version-specific commands [grumble, grumble]
# See: https://github.com/tmux/tmux/blob/master/CHANGES
run-shell 'tmux setenv -g TMUX_VERSION $(tmux -V | \
sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*//p")'
if-shell -b '[ "$(echo "$TMUX_VERSION < 2.1" | bc)" = 1 ]' " \
set -g mouse-select-pane on; set -g mode-mouse on; \
set -g mouse-resize-pane on; set -g mouse-select-window on; \
set -g message-fg red; \
set -g message-bg black; \
set -g message-attr bright; \
set -g window-status-bg default; \
set -g window-status-fg default; \
set -g window-status-current-attr bold; \
set -g window-status-current-bg cyan; \
set -g window-status-current-fg default; \
set -g window-status-bell-fg red; \
set -g window-status-bell-bg black; \
set -g window-status-activity-fg white; \
set -g window-status-activity-bg black"
# In version 2.1 "mouse" replaced the previous 4 mouse options
if-shell -b '[ "$(echo "$TMUX_VERSION >= 2.1" | bc)" = 1 ]' \
"set -g mouse on"
# UTF8 is autodetected in 2.2 onwards, but errors if explicitly set
if-shell -b '[ "$(echo "$TMUX_VERSION < 2.2" | bc)" = 1 ]' \
"set -g utf8 on; set -g status-utf8 on; set -g mouse-utf8 on"
# bind-key syntax changed in 2.4 -- selection / copy / paste
if-shell -b '[ "$(echo "$TMUX_VERSION < 2.4" | bc)" = 1 ]' " \
bind-key -t vi-copy v begin-selection; \
bind-key -t vi-copy V send -X select-line; \
bind-key -t vi-copy C-v rectangle-toggle; \
bind-key -t vi-copy y copy-pipe 'xclip -selection clipboard -in'"
# Newer versions
if-shell -b '[ "$(echo "$TMUX_VERSION < 2.9" | bc)" = 1 ]' " \
bind-key -T copy-mode-vi v send -X begin-selection; \
bind-key -T copy-mode-vi V send -X select-line; \
bind-key -T copy-mode-vi C-v send -X rectangle-toggle; \
bind-key -T copy-mode-vi y send -X copy-pipe-and-cancel 'xclip -selection clipboard -in'"
if-shell -b '[ "$(echo "$TMUX_VERSION >= 2.9" | bc)" = 1 ]' \
"set -g message-style fg=red,bg=black; \
set -g message-style bright; \
set -g window-status-style fg=default,bg=default; \
set -g window-status-current-style fg=default,bg=cyan,bold; \
set -g window-status-bell-style fg=red,bg=black; \
set -g window-status-activity-style fg=white,bg=black"
I raised an issue about the problems with tmux
's non-backward-compatibility here. The summary is that the tmux
devs will not support backward compatibility, nor will they adopt a version numbering scheme which highlights which versions contain breaking changes.
我提出了与问题一个问题tmux
的非向后兼容这里。总结是tmux
开发人员将不支持向后兼容性,也不会采用版本编号方案来突出显示哪些版本包含重大更改。
I raised an issue to support numeric comparators for %if
which was implemented in v3.0.
回答by Vincent Hsu
if-shell
doesn't always work. Instead, I use a shell script for loading the correct version of tmux.conf:
if-shell
并不总是有效。相反,我使用 shell 脚本来加载正确版本的 tmux.conf:
In .tmux.conf:
在 .tmux.conf 中:
run-shell "bash ~/.tmux/verify_tmux_version.sh"
In verify_tmux_version.sh:
在 verify_tmux_version.sh 中:
#!/bin/bash
verify_tmux_version () {
tmux_home=~/.tmux
tmux_version="$(tmux -V | cut -c 6-)"
if [[ $(echo "$tmux_version >= 2.1" | bc) -eq 1 ]] ; then
tmux source-file "$tmux_home/tmux_2.1_up.conf"
exit
elif [[ $(echo "$tmux_version >= 1.9" | bc) -eq 1 ]] ; then
tmux source-file "$tmux_home/tmux_1.9_to_2.1.conf"
exit
else
tmux source-file "$tmux_home/tmux_1.9_down.conf"
exit
fi
}
verify_tmux_version
For more details: https://gist.github.com/vincenthsu/6847a8f2a94e61735034e65d17ca0d66
更多详情:https: //gist.github.com/vincenthsu/6847a8f2a94e61735034e65d17ca0d66
回答by Micah Smith
This is kind of a hastle. The correct way to do this within tmux(not relying on an external shell script) combines features of both Vincent and jdloft's responses.
这有点匆忙。在 tmux 中执行此操作的正确方法(不依赖于外部 shell 脚本)结合了 Vincent 和 jdloft 响应的特性。
The if-shell
command in tmux is used as
if-shell
tmux 中的命令用作
if-shell [-bF] [-t target-pane] shell-command command [command]
(alias: if)
Execute the first command if shell-command returns success or the second command otherwise. Before
being executed, shell-command is expanded using the rules specified in the FORMATS section, including
those relevant to target-pane. With -b, shell-command is run in the background.
If -F is given, shell-command is not executed but considered success if neither empty nor zero (after
formats are expanded).
Note that tmux shell-command expansion will expand variables of the form #{pane_current_path}
but otherwise will leave the command alone.
请注意, tmux shell-command 扩展将扩展表单的变量,#{pane_current_path}
否则将不理会该命令。
More importantly, note that tmux uses/bin/sh -c
to execute the shell command we specify. Thus, the command must be POSIX compliant, so tests of the form [[
are not guaranteed to be portable. Modern Ubuntu and Debian systems, for example, symlink /bin/sh
to dash
.
更重要的是,注意 tmux用于/bin/sh -c
执行我们指定的 shell 命令。因此,该命令必须符合 POSIX 标准,因此[[
不能保证表单的测试是可移植的。例如,现代 Ubuntu 和 Debian 系统,符号链接/bin/sh
到dash
.
We want to run a POSIX compliant shell command that tests the tmux version and returns 0 (true) if the desired version is found.
我们想运行一个符合 POSIX 的 shell 命令来测试 tmux 版本并在找到所需版本时返回 0(真)。
if-shell '[ $(echo "$(tmux -V | cut -d" " -f2) >= 2.1" | bc) -eq 1 ]' \
'command if true' \
'command if false'
Example:
例子:
if-shell '[ $(echo "$(tmux -V | cut -d" " -f2) >= 2.1" | bc) -eq 1 ]' \
'set -g mouse on; set -g mouse-utf8 on' \
'set -g mode-mouse on; set -g mouse-resize-pane on; set -g mouse-select-pane on; set -g mouse-select-window on'
This correctly deals with the fact that we are doing floating point arithmetic, so bc
is required. Additionally, there is no need for an if/then/else/fi construct, as the [
operator produces a truthy value by itself.
这正确地处理了我们正在进行浮点运算的事实,所以bc
是 required。此外,不需要 if/then/else/fi 结构,因为[
操作符本身会产生一个真值。
A couple notes
几个注意事项
- Lines continuing onto the next line cannot have trailing comments or tmux will give an "unknown command" error message.
- The "command if false" can be omitted.
- Multiple commands for either true or false can be combined using
;
- The command is run on the underlying shell using
/bin/sh -c
. Other approaches that use[[
or other non-POSIX syntax are not guaranteed to work.
- 继续到下一行的行不能有尾随注释,否则 tmux 将给出“未知命令”错误消息。
- 可以省略“如果为假的命令”。
- 可以使用组合真或假的多个命令
;
- 该命令使用
/bin/sh -c
.[[
不保证使用或其他非 POSIX 语法的其他方法有效。
EDIT: A previous version of this answer used [[
, which doesn't work on systems that don't use bash. Replacing with [
solves this.
编辑:使用此答案的先前版本[[
,它不适用于不使用 bash 的系统。替换可以[
解决这个问题。
回答by Ingo Karkat
I also stumbled over configuration mismatches in different tmux versions. After reviewing all the solutions here and in this related question on SuperUser, I've implemented the following variant:
我还偶然发现了不同 tmux 版本中的配置不匹配。在查看了此处以及SuperUser 上的相关问题中的所有解决方案后,我实现了以下变体:
# Version-specific configuration can be placed in ~/.tmux/${TMUX_VERSION}/*.conf
run-shell "for conf in ~/.tmux/$(tmux -V | cut -d' ' -f2)/*.conf; do tmux source-file \"$conf\"; done"
With this, version-specific configuration can be put in (multiple) configuration snippets for a particular version. This is similar to the solution of @VincentHsu, but:
这样,可以将特定于版本的配置放入特定版本的(多个)配置片段中。这类似于@VincentHsu 的解决方案,但是:
- It does not require an external shell script.
- It does not segregate into fixed version ranges (... / 1.9 to 2.0 / 2.1 ...). Instead, one can use (sym)links to share a configuration snippet among multiple tmux versions.
- It does not hardcode a single filename for a version. By allowing multiple configuration snippets for each version, parts can be shared among versions while others are kept version-specific. This should offer the utmost flexibility.
- There's just a single configuration element in the original
~/.tmux.conf
. Other solutions like the one from @TomHale duplicate the version test for each configuration element.
- 它不需要外部 shell 脚本。
- 它不会分成固定的版本范围(... / 1.9 到 2.0 / 2.1 ...)。相反,可以使用(符号)链接在多个 tmux 版本之间共享配置片段。
- 它不会对版本的单个文件名进行硬编码。通过允许每个版本有多个配置片段,部分可以在版本之间共享,而其他部分则保持特定于版本。这应该提供最大的灵活性。
- 原始
~/.tmux.conf
. 其他解决方案,如来自@TomHale 的解决方案,重复每个配置元素的版本测试。
回答by bdellaterra
On some machines I was getting a false-positive result with the double bracket ('[[') syntax. So I came up with an alternative using awk:
在某些机器上,我得到了双括号 ('[[') 语法的误报结果。所以我想出了一个使用 awk 的替代方法:
# Enable mouse for different versions of tmux
# (If 'awk' exits with status 0, 'if-shell' evaluates to true)
# tmux < v2.1:
if-shell "tmux -V | awk '{exit !( < \"2.1\")}'" \
"setw -g mode-mouse on ; set -g mouse-select-pane on ; set -g mouse-resize-pane on ; set -g mouse-select-window on ;"
# tmux >= v2.1:
if-shell "tmux -V | awk '{exit !( >= \"2.1\")}'" \
"set -g mouse on ;"
回答by jdloft
Tmux's if-shell
can be used to check the ZSH version.
Tmuxif-shell
可用于检查 ZSH 版本。
[[ `tmux -V | cut -d' ' -f2` -lt 2.1 ]]
checks whether or not the tmux version is greater than or equal to 2.1. Using this we can set your mouse commands depending on the ZSH version.
检查 tmux 版本是否大于或等于 2.1。使用它,我们可以根据 ZSH 版本设置您的鼠标命令。
if-shell "[[ `tmux -V | cut -d' ' -f2` -lt 2.1 ]]" \
'set -g mode-mouse on; set -g mouse-resize-pane on; set -g mouse-select-pane on; set -g mouse-select-window on'
And set it for later versions of tmux:
并将其设置为更高版本的 tmux:
if-shell "[[ `tmux -V | cut -d' ' -f2` -ge 2.1 ]]" \
'set -g mouse on; set -g mouse-utf8 on'
回答by e-pirate
I have combined suggested solutions to a working one (tested on tmux 1.8 and 2.7):
我已经将建议的解决方案结合到一个有效的解决方案中(在 tmux 1.8 和 2.7 上测试过):
run-shell "tmux setenv -g TMUX_VERSION $(tmux -V | cut -c 6-)"
if-shell -b '[[ "$TMUX_VERSION" < "2.6" ]]' \
"bind w choose-tree -u"
if-shell -b '[[ "$TMUX_VERSION" < "2.2" ]]' \
"set -g status-utf8 on"
回答by BlueDrink9
Current latest release is 2.9a
, which throws off many of the direct comparisons used here.
当前最新版本是2.9a
,它抛弃了这里使用的许多直接比较。
My alternative makes use of sort -V
, which is much more robust for handling version comparisons.
我的替代方案使用sort -V
,它在处理版本比较时更加健壮。
# ver >= 2.3
[ ! "$(printf "%s\n%s" "$TMUX_VERSION" "2.3" | sort -V | head -n1)" == "$TMUX_VERSION" ]' \
"command"
# ver > 2.3
[ ! "$(printf "%s\n%s" "$TMUX_VERSION" "2.4" | sort -V | head -n1)" == "$TMUX_VERSION" ]' \
"command"
# ver < 2.3
[ "$(printf "%s\n%s" "$TMUX_VERSION" "2.3" | sort -V | head -n1)" == "$TMUX_VERSION" ]' \
"command"