7

У меня есть файл ~/.tmux/dev который выглядит так:

selectp -t 0    # select the first pane
splitw -h -p 50 # split it into two halves

selectp -t 1    # select the new, second (1) pane
splitw -v -p 50 # split it into two halves

selectp -t 0    # go back to the first pane
send-keys 'vim .' Enter

Если я запускаю tmux source-file ~/.tmux/dev изнутри сеанса tmux, он работает нормально.

Я хочу создать bash-скрипт, который открывает tmux и автоматически запускает эти команды.

Я пробовал бегать

tmux new 'tmux source-file ~/.tmux/dev'

но я вижу только две панели; панель с vim отсутствует.

Я прочитал, как заставить tmux открывать набор панелей, не вводя их вручную?, но перед установкой инструмента для управления настройками tmux я бы хотел узнать, что здесь происходит.

Заранее спасибо за любой свет, который вы можете пролить на эту тему.

2 ответа2

6

Вот что происходит:

  1. tmux new 'tmux source-file ~/.tmux/dev'

    new команды создают новый сеанс с одним окном, имеющим одну панель. Команда tmux source-file ~/.tmux/dev выполняется в этой новой панели.

    • Итак, у вас есть новый сеанс N (где N - некоторое число), с
    • одно окно N:0 (или что-то еще, у вас есть base-index ), с
    • одиночная панель N:0.0 (или что-то еще, для чего установлен base-pane-index ),
    • запустив команду tmux source-file ~/.tmux/dev .
  2. Команда source-file обрабатывается.

    1. Добавлены дополнительные панели.
    2. Панель 0 выбрана (пере).
    3. Затем команда send-keys « печатает » vim . + Введите на панели 0.
      Этот ввод игнорируется, потому что на этой панели только запущен клиент tmux, который отправил команду source-file .
  3. Клиент tmux завершает работу, закрывая панель 0.

Таким образом, неожиданным битом является то, что на панели 0 (т.е. N:0.0) выполняется (только) команда source-file которая игнорирует вашу «напечатанную» команду. Эта панель никогда не запускает интерактивную оболочку, которая может интерпретировать «напечатанную» команду.

Есть по крайней мере несколько способов это исправить:

  • Запустите ~/.tmux/dev с new-window чтобы на панели 0 выполнялась ваша «команда по умолчанию» (то есть, вероятно, интерактивная оболочка).

    Преимущество этого метода состоит в том, что он не предполагает, что на текущей панели запущена интерактивная оболочка, а также не предполагает, что текущая панель имеет значение 0 (то есть, что произойдет, если вы запустите исходную серию команд для панели, которая является частью уже разделенной области окно?). Это означает, что вы можете безопасно связать source-file ~/.tmux/dev с ключом, который вы можете запустить в любом контексте (поскольку он создает новое окно для всех своих панелей). Из оболочки вы можете запустить либо tmux source-file ~/.tmux/dev (чтобы создать новое окно в текущем сеансе), либо свой исходный tmux new 'tmux source-file ~/.tmux/dev' чтобы создать новый сессия.

    Небольшой недостаток этого метода заключается в том, что при запуске tmux new 'tmux source-file ~/.tmux/dev' в начальном окне все равно будет запускаться клиент, который отправляет source-file и довольно быстро завершает работу . Это означает, что ваше «главное окно» (с разделениями) будет на единицу выше, чем ваш base-index и будущее окно будет помещено перед «главным окном». Вы можете исправить это, используя что-то вроде этого:

    tmux new 'tmux move-window -t 99 \; source-file ~/.tmux/dev'
    

    Он перемещает (эфемерное) начальное окно в высокий индекс, так что new-window в ~/.tmux/dev будет в конечном итоге иметь base-index .

  • Используйте (например) tmux new 'tmux source-file ~/.tmux/dev ; zsh -l' чтобы панель заканчивала тем, что запускает интерактивную оболочку после завершения команды source-file .

    Недостаток в том, что вы в конечном итоге «жестко программируете» предпочитаемую оболочку в этой команде Также ввод с помощью send-keys (vim . + Enter) технически отправляется до запуска оболочки; это, вероятно, хорошо, но не всегда может быть полностью надежным.

    Вы можете избежать «жесткого кодирования» вашей оболочки, запросив tmux для команды default-command (или, если она не установлена, default-shell (или, если она не установлена, используя SHELL)), но это может оказаться более трудоемким, чем вы на самом деле хотеть сделать.

0

Я мог бы обойти подобную проблему следующим образом:

#!/bin/bash

tmp=$(mktemp --tmpdir=/tmp/).tmux

cleanup () {
        rm -f "$tmp"
}
trap cleanup EXIT

dump_cmd () {
        local i=$1
        shift
        echo "tcpdump -i $i -s 1500 \"port 67 or port 68\" -e $@"
}

cat <<-EOT > "$tmp"
        new-window
        send-keys '$(dump_cmd eno1)' Enter
        splitw -v -p 50
        send-keys '$(dump_cmd enp12s0f2)' Enter
EOT

tmux new 'tmux move-window -t 99 \; source-file '"$tmp"

# EOF #

Этот скрипт запускает два анализатора на двух интерфейсах в двух панелях.

PS

Можно просто использовать

        new-window '$(dump_cmd eno1)'
        splitw -v -p 50 '$(dump_cmd enp12s0f2)'

вместо этих четырех строк, но ^C для tcpdump тоже убьет эту панель. Это может быть не то, что вы хотите.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .