终端复用器 tmux 和 zellij
终端复用器(terminal multiplexer) tmux 和 zellij 的使用笔记
文章目录
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 server还没关掉, 直接
tmux kill-server
, 如果想使用之前启动的tmux server, 参考 tmux_server_version_is_too_old - osnosn - 博客园 (cnblogs.com)
tmux 开机启动没有会话
- tmux 写在脚本里开机启动, 需要
sudo su
, 然后再tmux ls
查看会话
Zellij
Zellij 简介
- Zellij官网 https://zellij.dev/
- Github仓库 zellij-org/zellij: A terminal workspace with batteries included (github.com), 主要是Rust写成的, 有终端的地方, Rust总会来帮帮场子
- Zellij文档 Introduction - Zellij User Guide
- Zellij 是一个终端工作空间, 具有类似 tmux 或者 screen 等终端复用器(terminal multiplexer) 的基本功能, 也包含许多内置功能, 允许用户扩展并创建自己的个性化环境, 如WebAssembly插件系统
- Zellij 中 Session 和 Pane 的概念和 tmux类似, 标签页 Tab 的概念对应 tmux 中的 Window
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)
备忘
- How to start zellij on every shell login like tmux · Discussion #1721 · zellij-org/zellij (github.com)
- zellij -d ? 如何后台运行?
- zellij run/edit 是在 pane 中运行的
- 检查配置 zellij setup --check
- 查看默认的配置文件 zellij setup --dump-config
欢迎扫描二维码关注微信公众号, 及时获取最新文章:
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)