我有一个.tmux.conf,我在安装了不同tmux版本的不同机器上使用。
我想设置不同的鼠标选项,具体取决于tmux版本。
在一台计算机上,我在另一台2.0
上有2.1
版本。
我说不出正确的意思
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"
当我找到文件时
$ tmux source-file .tmux.conf
我收到此消息
.tmux.conf:12: unknown command: set -g mouse-resize-pane on
我运行它的机器有版本2.1
所以它不应该设置四个选项。
我想在运行tmux 2.0或更少时设置四个选项,或者在运行tmux 2.1时设置一个选项。
此bash语句有效
$ tmux -V
tmux 2.1
$ if [[(( $(tmux -V | cut -c 6-) < 2.1 ))]];then echo $?;else echo $?;fi
1
答案 0 :(得分:34)
基于@ericx's answer和@thiagowfx's answer我将以下内容放在一起,涵盖版本2.0以后的listed incompatibilties:
# Version-specific commands [grumble, grumble]
# See: https://github.com/tmux/tmux/blob/master/CHANGES
run-shell "tmux setenv -g TMUX_VERSION $(tmux -V | cut -c 6-)"
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"
我提出了tmux
的非向后兼容here问题。摘要是tmux
开发人员不支持向后兼容性,他们也不会采用版本编号方案,突出显示哪些版本包含重大更改。
我还向support numeric comparators for %if
提出了一个问题。
答案 1 :(得分:17)
if-shell
并不总是有效。相反,我使用shell脚本来加载正确版本的tmux.conf:
在.tmux.conf中:
run-shell "bash ~/.tmux/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
了解更多详情: https://gist.github.com/vincenthsu/6847a8f2a94e61735034e65d17ca0d66
答案 2 :(得分:15)
这是一种麻烦。在tmux 中执行此操作的正确方法(不依赖于外部shell脚本)结合了Vincent和jdloft的响应功能。
tmux中的if-shell
命令用作
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).
请注意,tmux shell-command扩展将扩展#{pane_current_path}
形式的变量,否则将保留命令。
更重要的是,请注意tmux uses /bin/sh -c
来执行我们指定的shell命令。因此,命令must be POSIX compliant,因此不能保证形式[[
的测试是可移植的。现代的Ubuntu和Debian系统,例如,符号链接/bin/sh
到dash
。
我们希望运行一个POSIX兼容的shell命令来测试tmux版本,如果找到了所需的版本,则返回0(true)。
if-shell '[ $(echo "$(tmux -V | cut -d" " -f2) >= 2.1" | bc) -eq 1 ]' \
'command if true' \
'command if false'
示例:
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'
这正确地处理了我们正在进行浮点运算的事实,因此bc
is required。此外,不需要if / then / else / fi构造,因为[
运算符本身会产生一个真值。
几个笔记
;
/bin/sh -c
在底层shell上运行该命令。使用[[
或其他非POSIX语法的其他方法无法保证正常工作。 编辑:此答案的先前版本使用[[
,但不适用于不使用bash的系统。用[
替换解决了这个问题。
答案 3 :(得分:7)
Tmux的if-shell
可用于检查ZSH版本。
[[ `tmux -V | cut -d' ' -f2` -lt 2.1 ]]
检查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'
并将其设置为更高版本的tmux:
if-shell "[[ `tmux -V | cut -d' ' -f2` -ge 2.1 ]]" \
'set -g mouse on; set -g mouse-utf8 on'
答案 4 :(得分:6)
在某些机器上,我用双括号('[[')语法得到假阳性结果。所以我想出了一个使用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 < \"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 >= \"2.1\")}'" \
"set -g mouse on ;"
答案 5 :(得分:6)
我还发现了不同tmux版本中的配置不匹配问题。在此处和this related question on 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"
有了这个,特定于版本的配置可以放入特定版本的(多个)配置片段中。这类似于@VincentHsu的解决方案,但是:
~/.tmux.conf
中只有一个配置元素。其他解决方案(如@TomHale中的解决方案)会复制每个配置元素的版本测试。答案 6 :(得分:0)
我将建议的解决方案结合到了可行的解决方案中(在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"
答案 7 :(得分:0)
当前的最新版本是2.9a
,它引发了此处使用的许多直接比较。
我的选择是使用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"
答案 8 :(得分:0)
这不是替代方案,而是对已接受答案的扩展-(汤姆·黑尔的答案是最可靠,最完整的)。
要在.tmux.conf
中减少重复,可以将shell测试字符串存储在tmux env vars (available since 0.8 in 2008)中,并在运行时为if-shell
内插它们:
# Use which sed pattern actually works in the accepted answers
run-shell 'tmux setenv -g TMUX_VERSION $(tmux -V | sed -En "...")'
# Setup condition checks
V33_GTE='[ "$(echo "$TMUX_VERSION >= 3.3" | bc)" = 1 ]'
V33_LT='[ "$(echo "$TMUX_VERSION < 3.3" | bc)" = 1 ]'
# So on for other versions
# ...
### Example binding
# Toggle mouse
bind m set -g mouse on \; display 'Mouse: ON'
bind M set -g mouse off \; display 'Mouse: OFF'
# As of 3.1 you can annotate your keybindings
# As of 3.3 you can attach a note to existing bindings without setting the binding
# If running >= 3.3 , attach a note to the binding for `list-keys -N`
if "$V33_GTE" bind -N "Enable mouse mode" m
if "$V33_GTE" bind -N "Disable mouse mode" M
答案 9 :(得分:0)
我最近遇到了这个问题,我的解决方案是编写一个“ tmux-older-than”脚本:
from data-lake.libs.utils.operators import airflow_utils
这使tmux.conf更具可读性:
#! /bin/bash
TMUX_VERSION="$(tmux -V | cut -d" " -f2)"
test 1 -eq "$( echo "$TMUX_VERSION < $1" | bc)"
答案 10 :(得分:0)
我有这个配置很多年了。
tmux 2.4
tmux 2.4a
tmux next-3.3
等版本bc
命令# Tmux version before 2.4
if-shell -b '[ `tmux -V | cut -d" " -f2 | tr -d " |\-|.|[:alpha:]"` -lt 24 ]' \
'bind-key -t vi-copy v begin-selection; \
bind-key -t vi-copy Q cancel; \
bind-key -t vi-copy Enter cancel'
# Tmux version 2.4 onwards
if-shell -b '[ `tmux -V | cut -d" " -f2 | tr -d " |\-|.|[:alpha:]"` -ge 24 ]' \
'bind-key -T copy-mode-vi C-w send-keys -X cancel; \
bind-key -T copy-mode-vi C-u send-keys -X halfpage-up; \
bind-key -T copy-mode-vi C-j send-keys -X halfpage-down; \
bind-key -T copy-mode-vi C-l send-keys -X select-line'