#终端 #tmux #shell #持久性 #tty #终端窗口 #网络

应用程序 shpool

shpool 是一种建立轻量级持久性 shell 会话的机制,以优雅地处理网络断开。

6 个版本

0.6.3 2024年7月9日
0.6.2 2024年6月11日
0.6.1 2024年5月15日
0.6.0 2024年4月5日
0.1.0 2023年9月22日

#134网络编程

每月 40 次下载

Apache-2.0

310KB
5K SLoC

shpool

shpool 是一种通过允许创建由 shpool 拥有的命名 shell 会话来实现会话持久化的服务,这样在连接断开时,会话不会丢失。可以认为 shpooltmux 或 GNU screen 的更轻量级替代品。虽然 tmuxscreen 会接管整个终端并提供窗口分割和拼贴功能,但 shpool 只提供持久会话。这种方法的最大优点是 shpool 不会中断本地的滚动回溯或复制粘贴。

安装

从 crates.io 安装

运行

cargo install shpool
curl -fLo "${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/shpool.service" --create-dirs https://raw.githubusercontent.com/shell-pool/shpool/master/systemd/shpool.service
sed -i "s|/usr|$HOME/.cargo|" "${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/shpool.service"
curl -fLo "${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/shpool.socket" --create-dirs https://raw.githubusercontent.com/shell-pool/shpool/master/systemd/shpool.socket
systemctl --user enable shpool
systemctl --user start shpool
loginctl enable-linger

用法

通常,当通过 ssh 连接到远程主机时,使用 shpool 提供持久会话。为此,必须在远程主机上安装 shpool。客户端不需要额外软件。安装和设置后,典型的使用模式是在安装了 shpool 的主机上 ssh 登录,然后通过运行 shpool attach main 创建一个新的命名会话。这里 main 是会话的名称。您希望为每个连接到远程主机的终端创建一个单独的命名会话。如果您的连接断开或卡住,您可以再次 ssh 登录到远程主机,并通过运行 shpool attach main 再次连接到相同的命名会话。

如果您的终端卡住并且您强制关闭窗口,您可能会发现当您尝试重新连接时,shpool 仍然认为您的会话连接到了终端。这很可能是由于 ssh 代理在无望的希望中保持连接打开。您只需运行 shpool detach main 强制会话断开,这样您就可以连接了。

本README涵盖了基本用法,但您也可以查看维基百科以获取更多技巧和窍门。

故障排除

故障排除维基页面包含有关已知陷阱的一些信息。

配置

您可以通过编辑您的~/.config/shpool/config.toml文件来自定义一些shpool的行为。有关配置选项的深入讨论,请参阅CONFIG.md

Shell 配置

bash

如果您使用bash,您可能想确保将huponexit选项设置为在您离开shell时确保子进程退出。如果没有此设置,您在shell会话期间启动的后台进程将留在shpool守护进程的进程树中,并消耗内存。要设置此选项,请添加以下内容到您的~/.bashrc

shopt -s huponexit

子命令

shpool 守护进程

daemon子命令使shpool以守护进程模式运行。在此模式下,shpool将侦听传入的连接并打开子shell,在表中保留对它们的所有权。通常,此子命令不会由用户直接调用,而是从systemd单元文件中调用。

shpool attach

attach子命令连接到shpool 守护进程实例,传入一个名称。如果名称是新名称,则创建一个新的shell,如果它已存在,则只要没有其他终端连接到该会话,它就只是附加到现有的会话。可以使用--ttl标志来限制会话的持续时间。

shpool list

列出所有当前shell会话。

shpool detach

在不停止它们的情况下从一个或多个会话中分离出来。如果从没有会话名称参数的shpool会话内部运行,则将分离当前会话。

shpool kill

杀死一个命名的shell会话。

(可选)自动连接到 shpool

显式命名的会话

自己指定会话名称可以让您为每个会话分配逻辑角色,例如文本编辑。

ssh 配置

如果您通常使用同一台机器上的相同工作连接到少量会话,则客户端机器上的自定义ssh配置块可能是最佳选择。

为此,您可以在客户端机器的~/.ssh/config中添加名为edit的配置块,如下所示

Host = edit
    Hostname remote.host.example.com

    RemoteCommand shpool attach -f edit
    RequestTTY yes

然后,您可以使用ssh edit调用此内容。您需要为每个会话名称创建一个这样的块。

shell 函数

如果您希望在指定会话名称和目标机器时拥有更多灵活性,您可以为调用时指定这两个参数创建一个自定义shell函数。将以下内容添加到您的.bashrc,然后像这样调用它:shpool-ssh remote.host.example.com main

function shpool-ssh () {
    if [ $# -ne 2 ] ; then
        echo "usage: shpool-ssh <remote-machine> <session-name>" >&2
        return 1
    fi
    ssh -t "-oRemoteCommand=shpool attach -f $2" "$1"
}

基于本地 tty 的

而不是在连接时指定显式名称,您可以将系统设置为根据您的本地终端模拟器的tty号码自动生成一个shpool会话名称。为此,您可以在本地机器的~/.ssh/config中添加一个自定义ssh配置块,如下所示

Host = by-tty
    User remoteuser
    Hostname remote.host.example.com

    RemoteCommand shpool attach -f "ssh-$(basename $(tty))"
    RequestTTY yes

然后,您可以使用ssh by-tty调用此内容。您可以将相同的原理应用于自定义shell函数方法,使用$(basename $(tty))获取本地终端的唯一ID。

基于本地-tty的方法的优点是不需要指定会话名称,但如果需要关闭本地窗口并打开新的终端,可能会遇到问题,这通常发生在连接冻结而不是断开时。

与其他工具的比较

tmux 和 GNU screen

tmux 可能是最为人所知的会话持久化工具,GNU screen 也有类似的功能集,因此与 shpool 相比,可以认为它们属于同一类别。

shpooltmux 的主要区别在于,tmux 是一个终端复用器,这必然意味着它提供了会话持久化功能,而 shpool 只旨在成为一个会话持久化工具。与 tmux 不同,shpool 的理念是管理不同的终端是显示或窗口管理器的任务,而不是会话持久化工具的任务。每个操作系统都有自己的应用程序切换习惯,在切换终端时没有必要改变这些习惯。特别是对于使用 i3swayxmonad 等平铺窗口管理器的用户来说,tmux 的复用功能是多余的。

虽然 tmux 在远程渲染终端内容,并且只将当前视图绘制到屏幕上,但 shpool 直接将所有 shell 输出发送到用户的本地终端。这意味着所有的渲染都由单个终端状态机处理,而不是通过 tmux 的内部内存终端,然后再由本地终端格式化和重新渲染。这影响了性能,最重要的是,意味着使用 shpool 的终端将感觉完全本地化。滚动和复制粘贴将像在本地终端中一样工作,而使用 tmux 时可能会有不同的行为。

mosh

mosh 是另一个专注于提供持久远程 shell 会话的工具。它与其他工具的不同之处在于它有自己的网络协议,它从常规 ssh 中启动。像 tmux 一样,它远程渲染屏幕内容,只发送当前视图。它在尝试预测性猜测在网络延迟时显示给用户的正确输出方面相当独特。

shpoolmosh 的不同之处在于它与网络无关,仍然像大多数其他工具一样局限于单个机器。就像在 tmux 的例子中一样,mosh 将影响滚动和复制粘贴的方式,而 shpool 保持它们完全本地化。

dtachabducodiss

这些工具与 shpool 最相似。就像 shpool 一样,它们避免了复用,只是将原始字节发送回您,由您本地的终端进行渲染。虽然可以说 shpooltmux 的简化版本,但这些工具遵循相同的理念,并且更加专注于简单和做好一件事情。

shpool 致力于为只想持久化会话而不必过于关心的人提供简单而愉悦的体验,因此它具有一些额外的“舒适”功能,这些功能可能不适合这些工具对简单性的关注。

这些特性中最明显的是 shpool 和这些程序在重新附加方面的差异。虽然在正常操作中,shpool 不进行任何渲染和子集化壳输出,但它通过 shpool_vt100 包持续维护内存中的终端状态渲染。在重新附加时,shpool 将使用这个内存渲染重新绘制屏幕,这样你可以轻松地看到断开连接时你在哪里。这甚至允许你看到断开连接后生成的输出。

另一个这样的特性是自动提示前缀。当检测到你在使用已知的shell(目前为 bashzshfish)时,shpool 会自动将前缀注入到你的提示中,让你知道你所在的 shpool 会话的名称。这增加了一些有用的上下文,让你不会丢失对终端的控制,并有一些关于当前终端状态的提示。

还有一些 shpool 缺失而这些程序拥有的特性。特别是,似乎 dtachabduco 支持共享会话,而 shpool 只允许同时连接一个客户端到特定会话。可能还有更多,因为我对 shpool 的了解不如这些工具深入。

黑客开发

有关开发 shpool 的信息,请参阅 HACKING.md

依赖关系

~9–21MB
~292K SLoC