bash - sirve - variables de entorno linux
¿Cómo escribir una declaración if en.tmux.conf para configurar diferentes opciones para diferentes versiones de tmux? (6)
Tengo un .tmux.conf que uso en diferentes máquinas con diferentes versiones de tmux instaladas.
Quiero configurar diferentes opciones de mouse, dependiendo de la versión de tmux. En una máquina tengo la versión 2.0
en la otra 2.1
.
No entiendo bien su parte
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"
Cuando yo fuente el archivo
$ tmux source-file .tmux.conf
Me sale este mensaje
.tmux.conf:12: unknown command: set -g mouse-resize-pane on
La máquina donde la ejecuto tiene la versión 2.1
por lo que no debería configurar las cuatro opciones.
Quiero configurar las cuatro opciones cuando se ejecuta tmux 2.0 o menos o la única opción cuando se ejecuta tmux 2.1.
Esta declaración de bash funciona
$ tmux -V
tmux 2.1
$ if [[(( $(tmux -V | cut -c 6-) < 2.1 ))]];then echo $?;else echo $?;fi
1
Basándome en la respuesta de @ ericx y en la respuesta de @ thiagowfx, coloqué lo siguiente que cubre las incompatibilidades enumeradas a partir de la versión 2.0 en adelante:
# 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"
# 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
if-shell -b ''[ "$(echo "$TMUX_VERSION < 2.4" | bc)" = 1 ]'' /
"bind-key -t vi-copy v begin-selection; /
bind-key -t vi-copy V 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.4" | 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''"
El if-shell
Tmux solo ejecutará los siguientes comandos si el comando anterior se completó exitosamente, lo que significa que solo procederá si el código de error es igual a 0. En la página del manual:
Ejecute el primer comando si shell-command devuelve el éxito o el segundo comando de lo contrario.
Entonces usando la sintaxis de bash podemos usar
[[ `tmux -V | cut -d'' '' -f2` -lt 2.1 ]]
para verificar si la versión de tmux es mayor o igual a 2.1. El if-shell
, de nuevo, solo ejecutará los comandos del mouse si el comando anterior se ejecutó sin un código de error, por lo que al usar false
, podemos evitar que tmux ejecute los comandos del mouse:
if-shell "if [[ `tmux -V | cut -d'' '' -f2` -lt 2.1 ]]; then true; else false; fi" /
''set -g mode-mouse on; set -g mouse-resize-pane on; set -g mouse-select-pane on; set -g mouse-select-window on''
Luego puede usar esto para configurarlo para versiones posteriores de tmux si desea:
if-shell "if [[ `tmux -V | cut -d'' '' -f2` -ge 2.1 ]]; then true; else false; fi" /
''set -g mouse on; set -g mouse-utf8 on''
En algunas máquinas obtuve un resultado falso positivo con la sintaxis de doble corchete (''[['')]. Entonces se me ocurrió una alternativa usando 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 ;"
Esto es un poco rápido. La forma correcta de hacer esto dentro de tmux (sin depender de un script de shell externo) combina características de las respuestas de Vincent y jdloft.
El comando if-shell
en tmux se usa como
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).
Tenga en cuenta que la expansión del comando shell de tmux expandirá las variables de la forma #{pane_current_path}
pero de lo contrario, dejará el comando solo.
Más importante aún, tenga en cuenta que tmux uses /bin/sh -c
para ejecutar el comando de shell que especificamos. Por lo tanto, el comando debe ser compatible con POSIX , por lo que las pruebas de la forma [[
no se garantiza que sean portátiles. Los sistemas modernos de Ubuntu y Debian, por ejemplo, symlink /bin/sh
a dash
.
Queremos ejecutar un comando de shell compatible con POSIX que pruebe la versión de tmux y devuelva 0 (verdadero) si se encuentra la versión deseada.
if-shell ''[ $(echo "$(tmux -V | cut -d" " -f2) >= 2.1" | bc) -eq 1 ]'' /
''command if true'' /
''command if false''
Ejemplo:
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''
Esto aborda correctamente el hecho de que estamos haciendo aritmética de punto flotante, por lo que se requiere bc
. Además, no hay necesidad de una construcción if / then / else / fi, ya que el operador [
produce un valor verdadero por sí mismo.
Un par de notas
- Las líneas que continúan en la siguiente línea no pueden tener comentarios finales o tmux dará un mensaje de error de "comando desconocido".
- El "comando si es falso" se puede omitir.
- Se pueden combinar varios comandos para verdadero o falso usando
;
- El comando se ejecuta en el shell subyacente utilizando
/bin/sh -c
. No se garantiza que otros enfoques que utilizan[[
u otra sintaxis que no sean POSIX) funcionen.
EDITAR : una versión anterior de esta respuesta usó [[
, que no funciona en sistemas que no usan bash. Reemplazando con [
resuelve esto.
También tropecé con las discrepancias de configuración en diferentes versiones de tmux. Después de revisar todas las soluciones aquí y en esta pregunta relacionada sobre SuperUser , he implementado la siguiente variante:
# 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"
Con esto, la configuración específica de la versión se puede poner en (múltiples) fragmentos de configuración para una versión particular. Esto es similar a la solución de @VincentHsu, pero:
- No requiere un script de shell externo.
- No se segrega en rangos de versión fijos (... / 1.9 a 2.0 / 2.1 ...). En su lugar, se pueden usar enlaces (sym) para compartir un fragmento de configuración entre varias versiones de tmux.
- No codifica un solo nombre de archivo para una versión. Al permitir múltiples fragmentos de configuración para cada versión, las partes se pueden compartir entre versiones, mientras que otras se mantienen específicas de la versión. Esto debería ofrecer la máxima flexibilidad.
- Solo hay un elemento de configuración en el
~/.tmux.conf
original. Otras soluciones como la de @TomHale duplican la prueba de versión para cada elemento de configuración.
if-shell
no siempre funciona. En su lugar, uso un script de shell para cargar la versión correcta de tmux.conf:
En .tmux.conf:
run-shell "bash ~/.tmux/verify_tmux_version.sh"
En 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
Para más detalles: https://gist.github.com/vincenthsu/6847a8f2a94e61735034e65d17ca0d66