#tmux
#tmux
Вопрос:
(Отказ от ответственности: Я полностью осознаю, что существуют решения проблемы, которую я описываю ниже, которые включают в себя написание и вызов сценариев оболочки, которые взаимодействуют с запущенным сервером tmux, или установку необходимых переменных среды перед запуском сервера tmux. Я специально публикую эти вопросы, чтобы посмотреть, возможно ли решить эту проблему без использования таких скриптов.)
Краткое описание проблемы
В мой .tmux.conf
файл, я пытаюсь установить локальную переменную VALUE
для разных значения в зависимости от того, является ли переменная окружения FOO
была установлена перед вызовом tmux или нет. Затем я хочу использовать VALUE
в других командах tmux. К сожалению, я либо не могу установить VALUE
правильно, либо получить к ней доступ после того, как она была установлена.
Предыдущие попытки
Согласно тому, что я нашел на странице руководства и в других сообщениях вопросов и ответов, которые содержат пример кода tmux, существует несколько способов реализовать вышеуказанное.
Попытка 1
Сначала я попробовал использовать 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
.
Попытка 2
На странице руководства также упоминается, что команды могут быть условно выполнены с использованием %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 и некоторым подсказкам по форматированию; однако, что касается доступа к переменным среды, все, что я смог найти, это способ использования команд оболочки:
Кроме того, первая строка вывода командной строки может быть вставлена с помощью
#()
. Например,#(uptime)
будет указано время безотказной работы системы. При создании форматов tmux не ожидает завершения#()
команд; вместо этого используется предыдущий результат выполнения той же команды или заполнитель, если команда не выполнялась ранее.
Я не уверен, означает ли это, что мне нужно вызывать команды #()
дважды, чтобы избежать использования значения-заполнителя, что может быть возможной ошибкой с моей стороны.
Я также не смог найти способ легко распечатать результат #{}
команд для отладки этой части инструкции.
Краткое изложение вопросов
Хотя я был бы признателен за любые указания на информацию, которая может помочь мне решить эту проблему, наиболее насущными для меня вопросами являются:
- Почему
VALUE
устанавливается правильно, но не доступна дляRESULT
при попытке 1? - Как должно быть записано мое условие в попытке 2, чтобы убедиться, что
VALUE
установлено правильно?
Ответ №1:
Способ, которым tmux запускает конфигурацию, заключается в разборе файла конфигурации на набор команд, а затем их выполнении (существует очередь команд, поэтому файл конфигурации анализируется и добавляется в очередь, а затем выполняется из очереди). Итак, существуют различные этапы синтаксического анализа и выполнения.
Проблема, с которой вы сталкиваетесь при попытке 1, заключается в том, что if-shell запускается во время выполнения, но расширение $ VALUE происходит во время синтаксического анализа. ЗНАЧЕНИЕ не устанавливается при анализе команды set-environment.
При попытке 2 #() не обрабатывается внутри %, если это так, это не сработает. Однако вы можете использовать переменную непосредственно в форматах (если она установлена). %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, за исключением того, что это происходит при синтаксическом анализе, а не при выполнении — оба задают глобальную среду. Таким образом, вы могли бы избавиться от ЗНАЧЕНИЯ и сделать либо RESULT=bar, либо setenv -g RESULT bar внутри %if.)
Ответ №2:
Также вы можете использовать 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