终端复用器 tmux 和 zellij

本文介绍了tmux和Zellij这两个终端复用器,详细讲解了tmux的安装、常用命令和快捷键,以及如何通过脚本进行自动化配置。同时,提到了Zellij这个新兴的终端工作空间,强调了它的Rust背景、内置功能和WebAssembly插件系统,以及与tmux相似的Session和Pane概念。文章还包含了Zellij的安装、帮助和快捷键操作,并提供了使用示例。
摘要由CSDN通过智能技术生成

tmux

tmux 简介

在这里插入图片描述

tmux是一个终端复用器(terminal multiplexer), 可以在一个终端中切换多个程序, 分离它们(Detach, 在后台运行), 并将它们重新连接到另一个终端.

典型例子是ssh到远程计算机, 运行程序, 如果因为网络原因或者关毕连接, 会话终则进程灭, 正在运行的程序会直接停掉. 用tmux可以避免这个问题, 解绑了会话和窗口, ssh窗口断掉, tmux后台仍然可以运行程序, 下次连接, 还可以通过tmux重新进入会话, 并查看上下文.

tmux/tmux: tmux source code (github.com), 主要是C写成的, 截止20230103, 最新版本为 3.3a, 类似的程序还有 Screen - GNU Project - Free Software Foundation 和 Rust 写的 Zellij

tmux 的两大基本功能:

  • 终端中的窗口(Window)管理
  • 会话(Session)管理

一些概念和操作可以参考下图

在这里插入图片描述

tmux 安装

apt 方式: sudo apt install tmux

release 方式 Releases · tmux/tmux (github.com):

wget https://ghproxy.com/https://github.com/tmux/tmux/releases/download/3.3a/tmux-3.3a.tar.gz
tar -xvf tmux-*.tar.gz
cd tmux-3.3a
./configure && make -j$(nproc)
sudo make install

tmux 常用命令

# 查看版本
$ tmux -V
tmux 3.3a

# tmux 默认不支持鼠标向上滚动
# 可以在tmux窗口中输入以下命令开启鼠标滚动
$ tmux set mouse on

# Session
# 查看会话 ls 或 list-session
$ tmux ls
# 分离会话, 后台运行 detach 或 Ctrl+b,d
$ tmux detach
# 新建会话
$ tmux new -s <session-name>
# 接入会话 a 或 attach
$ tmux a -t <session-name>
# 杀掉会话
$ tmux kill-session -t <session-name>

# Layout
# 上下拆分, split 或 Ctrl+b,“
$ tmux split
# 左右拆分, split -h 或 Ctrl+b,%
$ tmux split -h
# 切换上下左右窗格 select-pane -U/-D/-L-R 或 Ctrl+b,方向键
$ tmux select-pane -U
# 平铺窗格(最大化/恢复) Ctrl+b,z

tmux 快捷键

# tmux窗口中 Ctrl+b,? 查看帮助
C-b C-b     Send the prefix key	发送前缀键
C-b C-o     Rotate through the panes 旋转窗格
C-b C-z     Suspend the current client 挂起当前客户端
C-b Space   Select next layout 选择下一个布局
C-b !       Break pane to a new window 打破窗格到一个新窗口
C-b "       Split window vertically 垂直分割窗口
C-b #       List all paste buffers 列出所有粘贴缓冲区
C-b $       Rename current session 重命名当前会话
C-b %       Split window horizontally 水平分割窗口
C-b &       Kill current window 关闭当前窗口
C-b '       Prompt for window index to select 提示要选择的窗口索引
C-b (       Switch to previous client 切换到上一个客户端
C-b )       Switch to next client 切换到下一个客户端
C-b ,       Rename current window 重命名当前窗口
C-b -       Delete the most recent paste buffer 删除最近的粘贴缓冲区
C-b .       Move the current window 移动当前窗口
C-b /       Describe key binding 描述键绑定
C-b 0       Select window 0 选择窗口0
C-b 1       Select window 1
C-b 2       Select window 2
C-b 3       Select window 3
C-b 4       Select window 4
C-b 5       Select window 5
C-b 6       Select window 6
C-b 7       Select window 7
C-b 8       Select window 8
C-b 9       Select window 9
C-b :       Prompt for a command 命令提示符
C-b ;       Move to the previously active pane 移动到先前活动的窗格
C-b =       Choose a paste buffer from a list 从列表中选择粘贴缓冲
C-b ?       List key bindings 列出键绑定
C-b C       Customize options 自定义选项
C-b D       Choose a client from a list 从列表中选择一个客户端
C-b E       Spread panes out evenly 将窗格均匀摊开
C-b L       Switch to the last client 切换到最后一个客户端
C-b M       Clear the marked pane 清除已标记的窗格
C-b [       Enter copy mode 进入拷贝模式
C-b ]       Paste the most recent paste buffer 粘贴缓冲区中最近的待粘贴项
C-b c       Create a new window 创建一个新窗口
C-b d       Detach the current client 分离当前客户端
C-b f       Search for a pane 搜索一个窗格
C-b i       Display window information 显示窗口信息
C-b l       Select the previously current window 选择先前的当前窗口
C-b m       Toggle the marked pane 切换标记的窗格
C-b n       Select the next window 选择下一个窗口
C-b o       Select the next pane 选择下一个窗格
C-b p       Select the previous window 选择上一个窗口
C-b q       Display pane numbers 显示窗格编号
C-b r       Redraw the current client 重绘当前客户端
C-b s       Choose a session from a list 从列表中选择会话
C-b t       Show a clock 显示时钟
C-b w       Choose a window from a list 从列表中选择一个窗口
C-b x       Kill the active pane 关闭活动窗格
C-b z       Zoom the active pane 缩放活动窗格
C-b {       Swap the active pane with the pane above 将活动窗格与上面的窗格交换
C-b }       Swap the active pane with the pane below 将活动窗格与下面的窗格交换
C-b ~       Show messages 显示消息
C-b DC      Reset so the visible part of the window follows the cursor 重置,使窗口的可见部分跟随游标
C-b PPage   Enter copy mode and scroll up 进入复制模式并向上滚动
C-b Up      Select the pane above the active pane 选择活动窗格上方的窗格
C-b Down    Select the pane below the active pane 选择活动窗格下面的窗格
C-b Left    Select the pane to the left of the active pane 选择活动窗格左侧的窗格
C-b Right   Select the pane to the right of the active pane 选择活动窗格右侧的窗格
C-b M-1     Set the even-horizontal layout 设置均匀水平布局
C-b M-2     Set the even-vertical layout 设置均匀垂直布局
C-b M-3     Set the main-horizontal layout 设置主水平布局
C-b M-4     Set the main-vertical layout 设置主垂直布局
C-b M-5     Select the tiled layout 选择平铺布局
C-b M-n     Select the next window with an alert 选择带有警报的下一个窗口
C-b M-o     Rotate through the panes in reverse 反向旋转窗格
C-b M-p     Select the previous window with an alert 选择带有警报的前一个窗口
C-b M-Up    Resize the pane up by 5 将窗格的大小向上调整5
C-b M-Down  Resize the pane down by 5 将窗格的大小向下调整5
C-b M-Left  Resize the pane left by 5 将窗格的大小向左调整5
C-b M-Right Resize the pane right by 5 将窗格的大小向右调整5
C-b C-Up    Resize the pane up 向上调整窗格的大小
C-b C-Down  Resize the pane down 向下调整窗格的大小
C-b C-Left  Resize the pane left 向左调整窗格的大小
C-b C-Right Resize the pane right 向右调整窗格的大小
C-b S-Up    Move the visible part of the window up 向上移动窗口的可见部分
C-b S-Down  Move the visible part of the window down 向下移动窗口的可见部分
C-b S-Left  Move the visible part of the window left 向左移动窗口的可见部分
C-b S-Right Move the visible part of the window right 向右移动窗口的可见部分

分类的可以参考这篇: tmux常用命令及快捷方式 - 知乎 (zhihu.com)

tmux 脚本

一些注意事项:

  • 不要用 ~ 表示home路径, 因为tmux脚本与systemd连用作为开机启动时是root下执行的, 此时~代表/root, 直接写全 /home/xxx
  • 每个tmux的窗格pane是独立的环境, 每个窗格都要重新source环境, 不能在外面source
  • 脚本最后不需要 tmux a -t <session-name>

下面是一个示例, 新建 session0 的会话, 会话里有 window0 的窗口, 窗口分成了4个窗格, 分别运行:

  • echo 'pane 0'
  • ping www.baidu.com -c 2
  • source /opt/ros/noetic/setup.bash; roscore
  • sleep 2; source /opt/ros/noetic/setup.bash; rosrun turtlesim turtlesim_node, 注: 最好不要在脚本中启动界面, 这里仅作为演示
#!/bin/bash

SESSION_NAME="session0"
WINDOW_NAME="window0"

# if session exists, delete it
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
    echo "Session '$SESSION_NAME' exists, deleting it"
    tmux kill-session -t "$SESSION_NAME"
fi

# create new session
echo "Creating new session '$SESSION_NAME'"
tmux new-session -d -s "$SESSION_NAME" -n "$WINDOW_NAME"

# split window to 4 panes
echo "Splitting pane"
tmux split-window -h -t "$SESSION_NAME:$WINDOW_NAME"
tmux split-window -v -t "$SESSION_NAME:$WINDOW_NAME".0
tmux split-window -v -t "$SESSION_NAME:$WINDOW_NAME".2

# you can use ctrl-b q to show pane numbers

# send commands to pane 0
echo "Sending commands to pane 0"
tmux send-keys -t "$SESSION_NAME:$WINDOW_NAME".0 "echo 'pane 0'" C-m

# send commands to pane 1
echo "Sending commands to pane 1"
tmux send -t "$SESSION_NAME:$WINDOW_NAME".1 "ping www.baidu.com -c 2" C-m

# send commands to pane 2
echo "Sending commands to pane 2"
tmux send -t "$SESSION_NAME:$WINDOW_NAME".2 "source /opt/ros/noetic/setup.bash; roscore" Enter

# send commands to pane 3
echo "Sending commands to pane 3"
tmux send -t "$SESSION_NAME:$WINDOW_NAME".3 "sleep 2; source /opt/ros/noetic/setup.bash; rosrun turtlesim turtlesim_node" Enter

# wait roscore to start up
roscore_pid=$(tmux capture-pane -p -t "$SESSION_NAME:$WINDOW_NAME".2 | grep -oP "process\[master\]: started with pid \K[][:digit:][]+")
while [ -z "$roscore_pid" ]; do
    echo "Waiting roscore to start up, pid: $roscore_pid"
    sleep 1
    roscore_pid=$(tmux capture-pane -p -t "$SESSION_NAME:$WINDOW_NAME".2 | grep -oP "process\[master\]: started with pid \K[][:digit:][]+")
done
# why this line is executed one digit short of the actual pid?
echo "Roscore started, pid: $roscore_pid"

查看 tmux a -t session0, 如图

在这里插入图片描述

tmux 常见问题

server version is too old for client

tmux 开机启动没有会话

  • tmux 写在脚本里开机启动, 需要 sudo su, 然后再 tmux ls 查看会话

Zellij

Zellij 简介

在这里插入图片描述

Zellij 安装

以下任选其一:

  • 官网下载 About Zellij, 解压出来是一个约16MB的单文件zellij(v0.34.4版本), 可以放到系统路径如 /usr/bin 或 /usr/local/bin 目录

  • Github Release下载 Releases · zellij-org/zellij (github.com)

  • Cargo安装 cargo install --locked zellij

  • 临时体验 bash <(curl -L zellij.dev/launch)

Zellij 帮助

$ ./zellij -h
zellij 0.34.4

USAGE:
    zellij [OPTIONS] [SUBCOMMAND]

OPTIONS:
    -c, --config <CONFIG>            Change where zellij looks for the configuration file [env:
                                     ZELLIJ_CONFIG_FILE=]
        --config-dir <CONFIG_DIR>    Change where zellij looks for the configuration directory [env:
                                     ZELLIJ_CONFIG_DIR=]
    -d, --debug                      Specify emitting additional debug information
        --data-dir <DATA_DIR>        Change where zellij looks for plugins
    -h, --help                       Print help information
    -l, --layout <LAYOUT>            Name of a predefined layout inside the layout directory or the
                                     path to a layout file
        --max-panes <MAX_PANES>      Maximum panes on screen, caution: opening more panes will close
                                     old ones
    -s, --session <SESSION>          Specify name of a new session
    -V, --version                    Print version information

SUBCOMMANDS:
    action               Send actions to a specific session [aliases: ac]
    attach               Attach to a session [aliases: a] 可以不输入全称, 只输入前几个字母
    convert-config
    convert-layout
    convert-theme
    edit                 Edit file with default $EDITOR / $VISUAL [aliases: e]
    help                 Print this message or the help of the given subcommand(s)
    kill-all-sessions    Kill all sessions [aliases: ka]
    kill-session         Kill the specific session [aliases: k]
    list-sessions        List active sessions [aliases: ls]
    options              Change the behaviour of zellij
    run                  Run a command in a new pane [aliases: r]
    setup                Setup zellij and check its configuration

子命令也有相应的help, 以 action 为例

$ zellij action -h
zellij-action
Send actions to a specific session

USAGE:
    zellij action <SUBCOMMAND>

OPTIONS:
    -h, --help    Print help information

SUBCOMMANDS:
    close-pane
            Close the focused pane
    close-tab
            Close the current tab
    dump-screen
            Dump the focused pane to a file
    edit
            Open the specified file in a new zellij pane with your default EDITOR
    edit-scrollback
            Open the pane scrollback in your default editor
    focus-next-pane
            Change focus to the next pane
    focus-previous-pane
            Change focus to the previous pane
    go-to-next-tab
            Go to the next tab
    go-to-previous-tab
            Go to the previous tab
    go-to-tab
            Go to tab with index [index]
    half-page-scroll-down
            Scroll down half page in focus pane
    half-page-scroll-up
            Scroll up half page in focus pane
    help
            Print this message or the help of the given subcommand(s)
    move-focus
            Move the focused pane in the specified direction. [right|left|up|down]
    move-focus-or-tab
            Move focus to the pane or tab (if on screen edge) in the specified direction
            [right|left|up|down]
    move-pane
            Change the location of the focused pane in the specified direction [right|left|up|down]
    new-pane
            Open a new pane in the specified direction [right|down] If no direction is specified,
            will try to use the biggest available space
    new-tab
            Create a new tab, optionally with a specified tab layout and name
    page-scroll-down
            Scroll down one page in focus pane
    page-scroll-up
            Scroll up one page in focus pane
    rename-pane
            Renames the focused pane
    rename-tab
            Renames the focused pane
    resize
            [increase|decrease] the focused panes area at the [left|down|up|right] border
    scroll-down
            Scroll down in focus pane
    scroll-to-bottom
            Scroll down to bottom in focus pane
    scroll-up
            Scroll up in the focused pane
    switch-mode
            Switch input mode of all connected clients [locked|pane|tab|resize|move|search|session]
    toggle-active-sync-tab
            Toggle between sending text commands to all panes on the current tab and normal mode
    toggle-floating-panes
            Toggle the visibility of all fdirectionloating panes in the current Tab, open one if
            none exist
    toggle-fullscreen
            Toggle between fullscreen focus pane and normal layout
    toggle-pane-embed-or-floating
            Embed focused pane if floating or float focused pane if embedded
    toggle-pane-frames
            Toggle frames around panes in the UI
    undo-rename-pane
            Remove a previously set pane name
    undo-rename-tab
            Remove a previously set tab name
    write
            Write bytes to the terminal
    write-chars
            Write characters to the terminal

Zellij 快捷键

在下方已有提示

在这里插入图片描述

如下:

  • 新建窗格 Alt + n
  • 窗格导航 Alt + <←↓↑→>Alt + <hjkl>
  • 调整窗格(面板)大小 Alt + <+->
  • 锁定或解锁: Ctrl + g, 使用后会自动屏蔽zellij的其他快捷键, 如ctrl + q退出等
  • 窗格快捷键: Ctrl + p, 按下后, 可以直接 ←↓↑→ 移动(也可以直接鼠标点), n 新建窗格, x关闭窗格, c 重命名窗格, d 下方新建窗格, r 右边新建窗格, f 全屏, z 显示或隐藏边框, w 悬浮(居中?), e 嵌入, p 选中下一个窗格, ENTER 进入选中窗格
  • 标签页快捷键: Ctrl + Tab, 按下后, n 新建类似浏览器的标签页, ←→或Tab切换标签页(当然也可以直接鼠标点), x 关闭标签页, r 重命名标签页, s 同步模式(多个窗格可以同时输入), ENTER 进入窗格
  • 调整大小的快捷键: Ctrl + n, 按下后, 使用 <←↓↑→> 或 <hjkl> 或 <+-> 调整窗格大小
  • 移动窗格的快捷键: Ctrl + h, 按下后, 使用 <←↓↑→> 或 n(下一个) 来移动窗格位置
  • 搜索: Ctrl + s
  • 会话(session): Ctrl + o, 按下后, d Detach离开zellij (后台运行, 可以zellij a session_name重新进入会话, session_name可以只输入前面几个字母), 打印 Session detached
  • 退出: Ctrl + q, 退出会话后, 不会后台运行, 打印 Bye from Zellij!

zellij 也兼容部分tmux快捷键, 如按下 Ctrl + b 后, d 分离会话, 方向键切换窗格 等

zellij 选中即复制, 默认也支持鼠标滚动

Zellij Layout

Zellij 使用 The KDL Document Language 作为配置语言

可以用zellij的layout实现类似tmux脚本的功能, sesseion 的 tab 分成了4个pane, 分别运行:

  • echo 'pane 0'
  • ping www.baidu.com -c 2
  • source /opt/ros/noetic/setup.bash; roscore
  • sleep 2; source /opt/ros/noetic/setup.bash; rosrun turtlesim turtlesim_node, 注: 最好不要在脚本中启动界面, 这里仅作为演示

新建一个 layout_file.kdl 文件, vscode也有kdl的插件

layout {
    pane split_direction="vertical" {
        pane {
            command "echo"
            args "pane"
        }
        pane {
            command "ping"
            args "www.baidu.com" "-c 2"
        }
    }
    pane split_direction="vertical" {
        pane {
            command "bash"
            args "-c" "source /opt/ros/noetic/setup.bash && roscore"
        }
        pane {
            command "bash"
            args "-c" "sleep 2 && source /opt/ros/noetic/setup.bash && rosrun turtlesim turtlesim_node"
        }
    }
}

运行

zellij --layout ./layout_file.kdl
# 或 zellij -l ./layout_file.kdl

# 或者给session起一个名字
# zellij --layout ./layout_file.kdl options --session-name session0

# 后台运行, 似乎不可行? 屏蔽掉界面程序也不可行?
# zellij --layout ./layout_file.kdl options --session-name session0 &
# zellij a session0

如图(ENTER重新运行命令, Ctrl-c关闭窗格pane)

在这里插入图片描述

官方的layout示例 Examples - Zellij User Guide 甚至可以把zellij当成一个类似vscode的编辑器来用

在这里插入图片描述

官方的另一个自动化任务和工作流的例子 Using Layouts for Personal Automation (zellij.dev)

在这里插入图片描述

其它组合使用的例子: 逐步搭建现代大一统终端(Alacritty +Zellij -> WezTerm) - 知乎 (zhihu.com)

备忘

欢迎扫描二维码关注微信公众号, 及时获取最新文章:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值