SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor

如何在手机上使用 Claude Code

Claude Code 运行在 VPS 的 tmux 会话中,手机仅通过 SSH 查看终端。本文介绍 SSH 密钥、应对移动网络波动的 mosh、tmux attach,以及手机键盘按键栏的实用设置。

在手机上使用 Claude Code:实际工作方式

本指南使用手机上的终端应用。Claude Code 运行在 VPS(虚拟专用服务器)上,位于持续保持打开的 tmux 会话中。手机会建立 SSH(安全 Shell)连接,连接到该会话,并在您查看会话期间保持连接。关闭应用后,代理仍会继续工作,因为该进程从未运行在手机上。

Claude Code 还提供 Remote Control:在会话中运行 /remote-control,即可通过 Claude 移动应用或浏览器使用它,同时进程仍运行在服务器上。

这就是整个设计。手机操作系统会在您切换离开应用几秒后将其挂起,因此在手机上启动的任何长时间任务都会停止。您从 Wi-Fi 切换到移动数据时,手机还会获得新的网络地址。这两个问题都可通过将进程运行在服务器上解决,手机只负责显示界面。

服务器上需要四项内容:用于保持会话的 tmux、用于登录的 SSH 密钥、用于应对网络变化的 mosh,以及 Claude Code 本身。手机端只需要一个带有可访问按键行的终端应用。

VPS 上的准备工作

SSH 和 tmux 部分使用一台小型 Ubuntu 24.04 主机即可。Claude Code 的要求更高。截至 2026 年 10 月,官方要求是在 x64 或 ARM64 处理器上运行 Ubuntu 20.04 或更高版本,并配备 4 GB 或更多 RAM。Claude Code 还需要付费 Claude 账户(Pro、Max、Team 或 Enterprise)、具有 API 访问权限的 Console 账户,或通过 Amazon Bedrock 等受支持的云提供商访问,因为免费的 Claude.ai 计划不包含 Claude Code。

使用具有 sudo 权限的普通用户配置主机,不要使用 root。如果服务器是新建的,请先完成新 VPS 上的前十分钟,因为完成用户和防火墙配置后,本指南后续的 SSH 修改会更简单。

sudo apt update && sudo apt install -y tmux mosh
curl -fsSL https://claude.ai/install.sh | bash
claude --version

安装程序会将二进制文件放在 ~/.local/bin/claude,而 claude --version 会输出类似 2.1.211 (Claude Code) 的行。如果输出 command not found,说明该目录尚未加入 PATH:退出登录后重新登录,然后使用 command -v claude 检查。claude doctor 会输出安装和设置诊断信息,但不会启动会话。

现在先使用笔记本电脑登录一次,再依赖手机操作。在项目目录中运行 claude,然后按照登录提示操作。此流程要求你在浏览器中打开 URL,再将代码带回终端;在手机屏幕上切换两个应用完成这些操作会比较慢。使用实体键盘完成一次登录后,凭据会保留在服务器上。

在 tmux 中启动 Claude Code,防止连接断开终止进程

tmux new -s claude
cd ~/projects/api
claude

使用 Ctrl-b,然后使用 d 分离会话。tmux 会输出 [detached (from session claude)],并将您返回 shell。现在,您可以关闭应用、失去网络信号,或将手机放入口袋。窗格中的进程仍会继续运行。

tmux ls
tmux attach -t claude

tmux ls 会为每个会话输出一行,例如 claude: 1 windows (created Thu Jul 30 09:14:02 2026)。tmux attach -t claude 会将您准确带回离开的位置,包括尚未完成的编辑。

这是因为 tmux 会运行自己的服务器进程。您的 shell 和 Claude Code 是该服务器的子进程,而不是 sshd 的子进程。SSH 连接结束时,内核会向附加到该连接的进程发送挂断信号 SIGHUP;tmux 服务器不属于这些进程。如果不使用 tmux,同样会导致连接断开的锁屏操作,也会使 Claude Code 在工具调用过程中停止。在 VPS 的 tmux 中运行 Claude Code 更详细地介绍了会话布局。

请在服务器上运行 tmux,不要在手机上运行。在已经附加的会话中输入 tmux 会输出 sessions should be nested with care, unset $TMUX to force;强制执行会导致两个前缀键相互冲突。

每次登录时自动附加

在触屏键盘上输入附加命令很快就会变得麻烦。将以下内容放在服务器上 ~/.profile 的末尾:

if command -v tmux >/dev/null 2>&1 && [ -z "$TMUX" ] && [ -t 1 ]; then
  exec tmux new-session -A -s claude
fi

如果名为 claude 的会话存在,new-session -A -s claude 会附加到该会话;如果不存在,则创建该会话,因此一条命令即可处理这两种情况。exec 会用 tmux 替换登录 shell,因此退出 tmux 后连接会关闭,而不是回到一个普通提示符。需要使用普通 shell 时,跳过该文件:ssh you@server -t "bash --noprofile"。

将其放在 ~/.profile 中,而不是 ~/.bashrc 中。对于非交互式 SSH 命令,Bash 还会读取 ~/.bashrc,但上面的 [ -t 1 ] 防护条件可防止文件传输期间启动 tmux。未加防护的启动命令如果输出内容,会导致传输协议因 Received message too long 等错误而中断。~/.profile 只对登录 shell 生效,而交互式 SSH 会话正是登录 shell。

Ubuntu 也会在 ~/.profile 中将 ~/.local/bin 添加到 PATH。如果登录后立即运行 claude 没有问题,但 tmux 内的 shell 提示 command not found,原因就是加载顺序。因此,应像上面这样从登录 shell 启动 tmux,而不要从跳过 profile 的脚本中启动。

这两个应用都支持 SSH 和 mosh,也都将密钥存储在应用中。区别在于操作界面。

Blink Shell 以命令为主。在提示符中输入 ssh you@server 或 mosh you@server,语法与桌面终端相同。输入 config 打开设置,Keys 部分会为您创建密钥对。

Termius 以表单为主。您先填写主机条目,然后在主机详情中将该主机从 SSH 切换为 Mosh。Termius 自带 mosh 实现,并支持 mosh 1.3.0 及更高版本,因此服务器仍需安装 mosh 软件包。

无论使用哪个应用,都应在应用内生成密钥,绝不要将现有私钥复制到手机上。应用会显示公钥部分,您只需将这一行添加到服务器上的 ~/.ssh/authorized_keys。为每台设备使用独立的 SSH 密钥并撤销密钥介绍了命名和撤销步骤。对于手机,这比笔记本电脑更重要。

启用终端应用自身的生物识别或密码锁定功能。否则,只要屏幕保持唤醒状态,一部已解锁的手机就等同于在服务器上打开的 shell。

Android:Termux

pkg upgrade
pkg install openssh mosh
ssh-keygen -t ed25519 -C "pixel"
cat ~/.ssh/id_ed25519.pub

Termux 在自己的软件源中提供 OpenSSH 和 mosh,因此 ssh、ssh-keygen 和 mosh 的行为与桌面系统相同。将显示的公钥行添加到服务器上的 ~/.ssh/authorized_keys,然后使用 mosh you@server 连接。

Android 屏幕键盘没有 Esc 键和 Ctrl 键,而 Claude Code 需要这两个键。Termux 可以绘制自己的按键行。在 ~/.termux/termux.properties 中添加一行:

extra-keys = [['ESC','|','/','HOME','UP','END','PGUP'],['TAB','CTRL','ALT','LEFT','DOWN','RIGHT','PGDN']]

然后运行 termux-reload-settings,按键行就会显示在键盘上方。同样的重新加载操作也会加载放置在 ~/.termux/font.ttf 中的等宽 TrueType 字体。

Termux 在后台运行时,Android 可能会将其停止。这里最多只需重新连接。会话和代理都在服务器上。

离开 Wi-Fi 后终端为什么会冻结,mosh 解决了什么问题?

SSH 连接是 TCP(传输控制协议)连接,而 TCP 连接由两端的地址和端口共同标识。离开 Wi-Fi 覆盖范围后,手机会从移动网络获取新地址,因此旧连接在两端都无法匹配。系统不会发出任何提示。终端只会停止响应,直到 TCP 放弃连接,然后 ssh 输出 client_loop: send disconnect: Broken pipe。要立即终止冻结的会话,请依次按 Enter、~ 和 .。

mosh(移动 shell)消除了这种故障模式。它使用 SSH 登录并启动 mosh-server 进程,读取服务器选择的 UDP(用户数据报协议)端口,然后关闭 SSH 连接。之后,两端使用共享会话密钥验证 UDP 数据报,因此会话由该密钥而不是地址标识。地址改变后,会话仍可继续。mosh 还会在本地回显输入,并在服务器返回不同内容时重新绘制终端,因此在速度较慢的移动网络上仍可正常使用。

mosh 使用 60000 到 61000 之间的 UDP 端口,因此请开放此范围:

sudo ufw allow 60000:61000/udp
sudo ufw status

使用 ufw 开放端口介绍了防火墙配置的其余部分。如果服务提供商在控制面板中提供单独的网络防火墙,也请在那里添加相同的端口范围,因为 ufw 规则无法影响位于服务器前方的过滤器。

mosh 常见的故障有两种。登录成功后出现停滞并显示 Nothing received from server on UDP port 60001.,表示 mosh-server 已启动,但客户端无法通过该 UDP 端口访问它。这通常表示手机与服务器之间的某个防火墙阻止了 mosh 端口范围内的 UDP 流量。连接报告找不到 mosh-server,表示服务器缺少该软件包,或登录 PATH 中没有该命令。请安装它,或使用 mosh --server=/usr/bin/mosh-server you@server 直接指定其路径。

如果服务器的登录区域设置不是 UTF-8,mosh-server 会尝试使用客户端提供的区域设置,并再次检查。如果仍无法提供 UTF-8,它才会拒绝运行,并报告 mosh-server needs a UTF-8 native locale to run.。请先修复服务器上的区域设置。

locale
sudo locale-gen en_US.UTF-8
sudo update-locale LANG=en_US.UTF-8

两端都需要使用 UTF-8 区域设置,mosh-server 还会应用客户端发送的区域设置。如果修复服务器后错误仍然存在,请在手机的终端应用中将 LANG 设置为 UTF-8 值;mosh 自己的 FAQ 也指出,mosh-client 可能需要这样设置。

mosh 有两项功能限制。其 README 表示,mosh 不支持 X 转发或 SSH 的非交互式用途,包括端口转发,因此预览 Claude Code 刚启动的 Web 应用仍需使用普通的 ssh -L 8080:127.0.0.1:8080 you@server。此外,它只同步当前可见的屏幕,因此自身不提供回滚缓冲区。不过这里不受第二项限制影响,因为 tmux 会保留回滚内容:Ctrl-b 后按 [ 进入复制模式,可使用拖动或箭头键滚动,按 q 退出。

让手机屏幕便于使用

服务器上的 ~/.tmux.conf 中有 4 行配置负责主要功能:

set -g mouse on
set -g status-position top
set -g default-terminal "tmux-256color"
set -g history-limit 20000

mouse on 将触摸拖动转换为滚动,将点按转换为窗格或窗口选择,从而替代大多数难以输入的前缀键。status-position top 将 tmux 状态栏从底部边缘移开,因为屏幕键盘及其建议栏会遮住该位置。default-terminal 将 tmux 向 Claude Code 宣布的终端名称固定下来。没有这一行时,tmux 会宣布其构建版本选择的名称。tmux 3.4 的 configure 脚本从 screen 开始,然后按顺序测试 screen-256color、tmux 和 tmux-256color;测试失败时会保留上一次选择。因此,找不到 tmux-256color terminfo 条目的构建最终会使用 tmux、screen-256color 或普通的 screen,颜色和框线绘制可能因此变得比应有的更差。

记住 4 个按键,其他操作就会很顺手。

  • Esc 会中断 Claude 当前的响应,但保留已经完成的工作,因此应将它放在拇指最容易触及的位置。
  • Ctrl+C 也会中断正在运行的操作。在空闲提示符下,第一次按下会清除输入,第二次按下会退出 Claude Code,因此它的作用更直接。
  • 连按两次 Esc 会清除草稿提示;在空提示符下,它会改为打开回退菜单。
  • 对于多行提示,请输入 \,然后按 Enter。这种方式适用于所有终端。Shift+Enter 只在少数桌面终端中原生支持,移动客户端不在其中。

避免使用拆分窗格。手机竖屏时宽度约为 40 列,因此垂直拆分后每个窗格只有 20 列,每个 diff 都会换行成难以阅读的内容。改用 tmux 窗口:Ctrl-b c 创建窗口,Ctrl-b n 切换到下一个窗口。如果第二个窗口最终运行了自己的 Claude Code 会话,两个会话可以直接互相交接工作,无需在触摸屏上的窗口之间复制文本。需要正确阅读 diff 时,将手机横过来。

屏幕上显示多少文本值得有意设置,因为输出样式会编辑每条回复背后的系统提示,而更简洁的样式意味着在手机上需要滚动浏览的屏幕更少。

小屏幕上的长时间会话主要是上下文管理问题,因此在尝试从火车上完成一整天的工作前,值得先阅读管理 Claude Code 上下文窗口。

锁定安全性:仅使用密钥,不使用密码

现在,手机上保存着一把可访问这台机器的密钥,而这台机器可以修改代码并运行命令。关闭密码认证。使用 drop-in 文件比直接编辑 sshd_config 更安全,因为 Ubuntu 的 sshd_config 顶部包含 /etc/ssh/sshd_config.d/*.conf,而配置项使用找到的第一个值。

sudo tee /etc/ssh/sshd_config.d/00-phone.conf >/dev/null <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
PermitRootLogin no
EOF
sudo sshd -t && sudo systemctl reload ssh

drop-in 文件按文件名顺序读取。检查 sudo sshd -T 中的 passwordauthentication no、kbdinteractiveauthentication no、pubkeyauthentication yes 和 permitrootlogin no;如果较早的文件设置了其中任何一项,就会优先使用该设置,必须在对应文件中修正。

sshd -t 会解析配置;配置有效时不输出任何内容。跳过这一步后,一个拼写错误就会导致 sshd 重新加载失败。保持当前会话打开,并从第二个连接进行测试后再关闭任何连接,因为错误的密钥会立即导致 Permission denied (publickey).;关闭密码后,也没有备用访问方式。此时的恢复路径是使用服务商的控制台。如果测试连接确实失败,请使用 ssh -v 重新连接,并在第一个会话仍然打开时完成修复,因为一条错误消息可能对应五种不同故障,而详细输出会告诉你实际遇到的是哪一种。

为每台设备使用独立的密钥。这样,手机丢失时,只需从 ~/.ssh/authorized_keys 删除一行,笔记本电脑仍可继续工作。使用共享密钥则意味着必须在你拥有的每台设备上更换密钥。

如果在 Ubuntu 24.04 上将 SSH 移到其他端口,请注意监听器属于 ssh.socket。systemd generator 根据 SSH 配置中的 Port 行生成该 socket,因此不需要 ListenStream override;但单独重启 ssh 会使服务器继续监听端口 22。将 Port 行放入 drop-in,允许 ufw 中的新端口,然后运行 sudo systemctl daemon-reload,再运行 sudo systemctl restart ssh.socket。VPS 上的 SSH 加固介绍了这些步骤以及其余攻击面。

用于 SSH 的 fail2ban在关闭密码后增加的安全性很小,因为猜测出的密码根本无法通过认证。它能减少日志噪声,从而更容易发现真实的登录尝试。

更安全的方案是让 SSH 不暴露在公网中。将服务器置于自行托管的 WireGuard VPN之后,按需在手机上建立隧道,并仅在隧道上为 sshd 配置 ListenAddress。mosh 可通过该隧道工作,因为两端都使用 UDP。需要注意的是,隧道会增加数据包开销;如果大文件传输停滞,请在手机的 WireGuard 配置中降低 MTU(最大传输单元)。

最后说明一下这种工作方式。使用手机时,你需要在一次只能显示几行 diff 的屏幕上批准权限提示。这正是应保留防护措施、而不是关闭它们的原因。还要检查会话启动时使用的权限模式,因为从 Claude Code v2.1.283 开始,auto mode 现在是交互式终端会话的内置启动模式,它会直接修改工作目录中的文件,而不会停下来请求确认。在 VPS 上安全运行 Claude Code介绍了在主要入口变成触摸屏之前,值得设置的用户和目录限制。

重新连接后发现异常时

tmux attach 输出 no server running on /tmp/tmux-1000/default 表示 tmux 在该套接字上未找到服务器。通常表示服务器已退出,而这几乎总是因为机器已重启。使用 uptime 检查。如果主机没有重启,而 pgrep tmux 仍显示服务器,这本身并不表示套接字文件已被删除,因为 -L 和 -S 标志允许服务器监听其他套接字。如果您使用其中一个标志启动了 tmux,请将相同的标志传递给 tmux attach。如果套接字确实被意外删除,pkill -USR1 tmux 会要求服务器重新创建套接字;tmux 手册指出,如果任一父目录缺失,此操作会失败。来自自动安全更新的内核更新需要重启才能生效,但 unattended-upgrades 仅在启用 Unattended-Upgrade::Automatic-Reboot 时自动重启;其默认值为 false。主机重启后不会保留 tmux 会话,因此应将任何 Claude Code 运行视为可重新启动的任务。

can't find session: claude 不同。tmux 服务器正在运行,但不存在该名称。tmux ls 显示实际存在的内容。

如果您看到原本运行 Claude Code 的位置变成普通 shell 提示符,说明进程已结束,但会话尚未结束。查看 dmesg -T | tail,查找类似 Out of memory: Killed process 4821 (claude) 的行;该行可确认进程是因内存不足而被终止的。检查提示符上方 shell 的回滚内容,查看是否有其他退出消息。

窗口恢复后尺寸错误、边缘被截断或周围出现空白,说明有两个客户端以不同尺寸连接。默认情况下,tmux 3.4 会将窗口调整为最近有活动的客户端尺寸(window-size latest),因此仍以 200 列连接的笔记本电脑客户端和宽度为 40 列的手机客户端会交替调整窗口大小。连接时分离其他客户端:tmux attach -d -t claude。

FAQ

我可以直接在手机上运行 Claude Code,而不是在 VPS 上运行吗?

终端 CLI 不支持 Android 或 iOS。截至 2026年10月,支持的平台包括 macOS、Windows、Ubuntu 20.04 或更高版本、Debian 10 或更高版本,以及 Alpine 3.19 或更高版本,并且需要 4 GB 或更多 RAM。Android 和 iOS 不在支持列表中。手机还会让应用进入休眠状态,并且持续改变网络地址,这些情况无法满足长时间运行代理的要求。请在服务器上运行它,并将手机用作显示终端。

关闭应用或失去信号后,会话还会保留吗?

会,而且这由两个独立组件共同实现。tmux 会让进程继续在服务器上运行,因此连接断开时进程不会终止。mosh 会在地址变化后保持连接,因此从 wifi 切换到移动数据时甚至不需要重新连接。使用普通 SSH 且未使用 tmux 时,连接断开会发送 SIGHUP,Claude Code 会在任务进行到一半时停止。

为什么 mosh 连接后没有任何显示?

登录成功后出现卡住状态,并显示 Nothing received from server on UDP port 60001.,表示客户端无法通过该 UDP 端口访问 mosh-server,通常说明防火墙阻止了 UDP 60000 到 61000。请在 ufw 中添加该端口范围,并在服务商的网络防火墙中再次添加,因为大多数控制面板将其作为独立的控制项。如果 mosh 报告找不到 mosh-server,说明服务器缺少该软件包,或者其登录 PATH 未包含该命令:使用 sudo apt install mosh 安装,或使用 mosh --server=/usr/bin/mosh-server you@server。

没有 Esc 键时,如何使用键盘中断 Claude Code?

添加一行按键。Termux 可在 ~/.termux/termux.properties 中使用 extra-keys 配置该按键行,Termius 和 Blink 也都提供可在设置中编辑的按键行。Esc 会中断正在运行的响应,同时保留已完成的工作。Ctrl+C 也会中断响应,但在空闲提示符处连续按两次会退出 Claude Code,因此应优先使用 Esc。

通过互联网开放 SSH 是否足够安全?

关闭密码认证后,唯一能够成功认证的凭据就是不会离开设备的密钥。对于可以重建的机器而言,这属于合理的风险。请为每台设备使用独立的密钥,这样手机丢失时只需从 authorized_keys 中删除一行。如果您不想在公共端口上提供 SSH 服务,可以将服务器置于 WireGuard 后面,并让 sshd 监听隧道地址。

这篇文章对您有帮助吗?