5 个版本

0.2.3 2021 年 1 月 16 日
0.2.2 2021 年 1 月 1 日
0.2.0 2020 年 12 月 26 日
0.1.1 2020 年 12 月 22 日
0.1.0 2020 年 12 月 22 日

命令行工具 中排名 2711

每月下载量 23

MIT 许可证

245KB
6K SLoC

Airmux

又一款 tmux 会话管理器。需要 Tmux 2.6+。

目录

安装

Cargo 安装

如果您在系统上安装了 cargo

$ cargo install airmux

手动安装

$ AIRMUX_TARGET="x86_64-unknown-linux-gnu" # Check the list of available targets on the releases page
$ curl -o airmux -fsSL "https://github.com/dermoumi/airmux/releases/latest/download/airmux-$AIRMUX_TARGET"
$ chmod +x airmux
$ sudo mv airmux /usr/local/bin/

您可以在 发布页面 检查可用目标列表。

使用方法

USAGE:
    airmux [OPTIONS] <SUBCOMMAND>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -c, --config-dir <DIR>    configuration directory to use [env: AIRMUX_CONFIG=]

SUBCOMMANDS:
    debug     Print tmux source without actually running tmux
    edit      Create or edit a project
    freeze    Save current tmux session as a project file (commands not included)
    help      Prints this message or the help of the given subcommand(s)
    kill      Kill tmux session that matches the project
    list      List all configured projects
    remove    Remove a project (does not affect loaded tmux sessions)
    start     Start a project as a tmux session

Airmux 项目示例

# Set project working directory
working_dir: ~/projects/django_project/

# Run dev redis and postgresql instances when the session is created
on_create:
  - >- # yaml-multiline.info
    docker run -itd
    --name r-redis
    --publish 16379:6379
    redis || docker start r-redis
  - >-
    docker run -itd
    --name r-postgresql
    --publish 15432:5432
    --env POSTGRES_PASSWORD=hunter2
    --volume $HOME/.postgresql:/var/lib/postgresql/13
    postgres:13 || docker start r-postgresql

# Stop dev redis and postgresql when the session is stopped
on_stop: docker stop r-redis r-postgresql

# Activate python virtualenv on each of this session's panes
pane_commands: source .venv/bin/activate

# Clear all panes after creation (akin to pression CTRL+L)
clear_panes: true

# Define tmux windows
windows:
  # First window contains 3 panes: an empty shell, the dev server output and the worker output
  - main:
    panes:
      -
      - split: v # Split previous pane by half, vertically
        send_keys: python manage.py runserver # command is typed but not executed
      - split: h # split previous pane by half, horizontally
        command: python celery --app django_project worker
  # Second window contains logs of the previously run docker containers
  - container-logs:
    panes:
      - docker logs -f r-postgresql
      - docker logs -f r-redis

启动会话

$ airmux start my_project [param1 [param2...]]

参数可以在项目文件中以 $1$2 等形式访问

从另一个 tmux 会话运行

当从另一个 tmux 会话内部执行 airmux 时(即当 TMUX 环境变量已设置时),它使用 tmux switch-client 而不是 tmux attach-session,允许快速在项目之间切换。

如果将 --switch 传递给 start(或如果设置了 AIRMUX_FORCE_SWITCH 环境变量),无论是否设置了 TMUX,它都会使用 tmux switch-client

创建和编辑项目文件

使用以下方式创建或编辑项目

$ airmux edit <my_project>

默认编辑器($EDITOR)用于打开文件。您可以使用 --editor 选项指定要使用的编辑器

$ airmux edit --editor="code -w" my_project

项目定义

所有字段都是可选的,但至少需要一个。

# Name of the session in tmux. Cannot contain a dot (.) or colon (:) (alias: name)
session_name: <project name>

# Tmux command to use. Can also be overritten by using `--command` when running airmux
tmux_command: tmux

# Flags and options to pass to tmux every time it's executed
tmux_options: <empty>

# Socket name to pass to tmux (alias: socket_name)
# Equivalent to adding `-L <socket_name>` to `tmux_options`
tmux_socket: <empty>

# Working directory for all the windows in this session (alias: root)
# If declared and left empty or set to ~ (null in Json), defaults to $HOME instead.
working_dir: <current working directory>

# The starting index for windows (should be a non-negative integer)
window_base_index: 1

# The starting index for panes (should be a non-negative integer)
pane_base_index: 1

# Name of index window that's selected on startup
startup_window: <first window>

# Index of pane that's selected on startup
startup_pane: <first pane>

# Shell commands to execute before the session is attached (alias: on_project_start)
# Available substitutions: __TMUX__, __SESSION__
on_start:

# Shell commands to execute before the session is attached the first time (alias: on_project_first_start)
# Available substitutions: __TMUX__, __SESSION__
on_first_start:

# Shell commands to execute before the session is re-attached (alias: on_project_restart)
# Available substitutions: __TMUX__, __SESSION__
on_restart:

# Shell commands to execute after the session is detached (alias: on_project_exit)
# Available substitutions: __TMUX__
on_exit:

# Shell commands to execute after the session is destroyed (alias: on_project_stop)
# Available substitutions: __TMUX__
on_stop:

# Shell commands to execute after the session (with all its content) is created
# Available substitutions: __TMUX__, __SESSION__
post_create:

# Shell commands to execute when a pane is created (before pane_commands are typed in)
# Available substitutions: __TMUX__, __SESSION__, __WINDOW__, __PANE__
on_pane_create:

# Shell commands to execute after a pane is created (after pane_commands are typed in)
# Available substitutions: __TMUX__, __SESSION__, __WINDOW__, __PANE__
post_pane_create:

# Commands that are executed in the shell of each pane (alias: pre_window, pane_command)
pane_commands:

# Whether or not to clear (send ctrl+L) all of the underlying panes after creation
clear_panes: false

# Whether or not the session automatically attaches on creation (can't use both)
attach: true
detached: false

# Window declarations (alias: window)
windows: <default empty window>

命令

命令可以以字符串或字符串列表的形式编写

# Run a single command when attaching the session
on_start: echo command1
# Run 3 commands when detaching the session
on_stop:
    - echo command2
    - echo command3
    - echo command4

注意:Airmux 总是会删除 \r 字符,并将 \n 替换为空格字符( ),即使你没有使用正确的 YAML 多行语法。

所有命令都会被执行,不受前一个命令退出状态的影响。

关于 on_exit 和 on_stop 的说明

当启动具有 on_exiton_stop 命令的项目时,Airmux 会将全局的 exit-empty 选项设置为 off,以防止 tmux 在最后一个会话关闭时停止服务器。

这样做是为了确保任何 on_exiton_stop 命令都会被执行,即使最后一个会话被关闭。

但是请注意,exit-empty 选项仅存在于 tmux 2.7+ 中,且对于低于该版本的版本没有解决方案。

窗口定义

所有字段都是可选的,但至少需要一个。

windows:
  # Window names should not contain dots (.) and colons (:)
  # You can have multiple windows with the same name
  # It can also have a null (~) name, in which case it'll use default tmux behavior
  - window_1_name:
      # Working directory for the window (alias: root)
      # If declared and left empty or set to ~ (null in Json), defaults to $HOME instead.
      working_dir: <project's working directory>

      # Layout, can be: even-horizontal, even-vertical, main-horizontal, main-vertical, tiled
      # Or a custom layout, see `Layouts` section for details. Can't use with custom pane splits.
      layout: <no_layout>

      # Shell commands to execute when a window is created (before child pane panes are configured)
      # Available substitutions: __TMUX__, __SESSION__, __WINDOW__
      on_create:

      # Shell commands to execute after a window is created (after all child panes are configured)
      # Available substitutions: __TMUX__, __SESSION__, __WINDOW__
      post_create:

      # Shell commands to execute when a pane is created (before pane_commands are typed in)
      # Available substitutions: __TMUX__, __SESSION__, __WINDOW__, __PANE__
      on_pane_create:

      # Shell commands to execute after a pane is created (after pane_commands are typed in)
      # Available substitutions: __TMUX__, __SESSION__, __WINDOW__, __PANE__
      post_pane_create:

      # Commands that are executed in the shell of each pane (alias: pre, pane_command)
      pane_commands:

      # Whether or not to clear (send ctrl+L) all of the underlying panes after creation
      clear_panes: false

      # List of panes
      panes: <default empty pane>

Windows 也可以定义为单个命令或多个命令(每个窗口一个)

windows:
  - echo "single pane nameless window"
  - single_pane: "single pane named window"
  - ~:
    - echo "pane 1 of a nameless window"
    - echo "pane 2 of a nameless window"
  - multiple_panes:
    - echo "pane 1 of a named window"
    - echo "pane 2 of a named window"

此外,窗口定义字段可以与名称处于同一级别,只要它是第一个键

windows:
  - window_name:
    layout: main-vertical
    panes:
      - echo cmd1
      - echo cmd2

您还可以使用 name(别名:title)字段覆盖窗口名称

windows:
  - layout: main-vertical
    name: ~
    panes:
      - echo cmd1
      - echo cmd2

面板定义

panes:
  - # Working directory for the pane (alias: root)
    # If declared and left empty or set to ~ (null in Json), defaults to $HOME instead.
    working_dir: <window's working directory>

    # The pane to split from when creating this one. Does not apply to the first pane.
    # These indexes follow the same order as in the project file and always start with pane_base_index
    split_from: <previous pane>

    # How to split when creating this pane (v, vertical, h, horizontal)
    split: horizontal

    # Size of this pane (number of columns/rows or a percentage)
    split_size: 50%

    # Whether or not to send a clear combination (Ctrl+L) after typing the pane commands
    clear: false

    # Shell commands to execute when a pane is created (before pane_commands are typed in)
    # Available substitutions: __TMUX__, __SESSION__, __WINDOW__
    on_create:

    # Shell commands to execute after a pane is created (before pane_commands are typed in)
    # Available substitutions: __TMUX__, __SESSION__, __WINDOW__
    post_create:

    # Commands to type and run in this pane's shell (alias: command)
    commands:

    # Key strokes that are typed but not executed... as long as they don't contain a new line
    send_keys:

布局

除了 5 个默认布局之外,您还可以提供自定义布局

windows:
  - layout: 'fc16,277x30,0,0{137x30,0,0,2,139x30,138,0,3}'

您可以在《Tao of tmux》中了解更多关于自定义布局的信息

当在窗口上使用布局时,所有 splitsplit_size 都不能用于底层窗格。

环境变量和参数展开

项目文件支持变量的展开(任何地方,不仅仅是字符串值)

windows:
  # Expanding the User environment variable
  - $USER:
  # Alternative syntax, allows you to use mid-words
  - ${EDITOR}_window:
  # Expansion with a fallback value for when the variable is not set
  - ${SOME_VAR:-fallback_value}:

这也意味着每次你需要写入 $ 时,都需要将其转义为 $$

此外,传递给 airmux startairmux kill 的任何额外值都可用作 $1$2 等...

windows:
  - pipenv run server ${1:-8000}
# pipenv run server will run at port 8080 instead of the default 8000
$ airmux start my_project 8080

本地项目文件

接受项目名称的命令可以在没有它的情况下调用,以使用本地的 .airmux.(yml|yaml|json) 项目文件。

如果没有本地项目文件,Airmux 将检查当前工作目录的每个祖先目录,直到找到为止。否则,它将默认为当前目录上的 .airmux.yml

在创建时,您可以指定本地项目文件的扩展名

$ airmux edit --ext json

其他命令

列出所有项目

$ airmux list

停止与项目对应会话

$ airmux kill my_project

删除项目

$ airmux remove my_project

调试会话创建

$ airmux debug my_project

打印传递给 tmux source 创建会话的所有命令,包括钩子和一切。

您可以将输出保存下来,并直接使用,而无需通过 airmux 传递。只要 tmux 服务器已经运行即可。此外,它永远不会附加会话。

$ airmux debug my_project | tmux source

将当前会话保存为项目

$ airmux freeze my_project

除非传递了 --no-input 标志,否则在覆盖现有项目之前,系统将提示您确认。

您还可以将项目文件打印到 stdout,而不是打开文本编辑器

$ airmux freeze --stdout

依赖关系

~5–16MB
~204K SLoC