远端跑一个 CodeMote 常驻会话、本地按需接入同一工作目录

文章导读
把 CodeMote 常驻会话当成远端工作的固定入口、本地按需接入,需要先确认三件事:退出终端后会话进程是否还在、接入账号对工作目录是否真有写权限、两台设备同时写同一个文件时实际是覆盖还是拒绝。这三点都能用命令、日志和页面行为验证,不需要凭感觉判断。顺序建议是先定会话形态,再定目录权限,然后用一个测试文件摸清多端写入行为,最后把重启后的核对流程固定下来。
📋 目录
  1. 一 常驻会话的启动方式与退出后是否保留现场
  2. 二 工作目录的挂载与读写权限设置
  3. 三 两台设备同时接入时的文件冲突观察
  4. 四 远端重启后会话恢复与目录状态确认
  5. 五 什么任务适合常驻、什么任务用一次性会话
A A

把 CodeMote 常驻会话当成远端工作的固定入口、本地按需接入,需要先确认三件事:退出终端后会话进程是否还在、接入账号对工作目录是否真有写权限、两台设备同时写同一个文件时实际是覆盖还是拒绝。这三点都能用命令、日志和页面行为验证,不需要凭感觉判断。顺序建议是先定会话形态,再定目录权限,然后用一个测试文件摸清多端写入行为,最后把重启后的核对流程固定下来。

建议用 tmux 或 systemd 用户实例托管一个命名会话,工作目录放在共享组下并开启 setgid,接入前用 ls -ld、namei -l 确认权限位;两台设备同时写入时不要假定会自动合并,先在测试文件上走一遍先后修改流程,记录是覆盖、拒绝还是生成副本;远端重启后按清单核对会话、挂载点和目录内容,再开始正式工作。工作目录含凭据或客户数据时,优先考虑一次性会话。

常驻会话的启动方式与退出后是否保留现场

判断 CodeMote 会话是一次性还是长期存在,依据不是说明文档,而是断开终端后进程是否仍活着。下面两种启动骨架按环境选一种,命令名与参数需要替换成实际安装版本提供的写法,`--workdir` 与 `--log` 是可替换的示例参数。

# 方式一:tmux 托管,登录后手动拉起
tmux new-session -d -s codemote -c /srv/work
tmux send-keys -t codemote 'codemote serve `--workdir` /srv/work `--log` /srv/work/.codemote/session.log' C-m

# 方式二:交给 systemd 用户实例,支持开机自启
systemctl `--user` enable `--now` codemote.service
systemctl `--user` status codemote.service

启动后退出 ssh,再重新登录检查现场是否保留:

tmux ls
ps -eo pid,ppid,etime,cmd | grep -i codemote
tail -n 50 /srv/work/.codemote/session.log

tmux 会话仍在、ps 里进程仍在、日志没有正常退出记录,说明这是长期会话;如果进程随终端一起消失,说明默认是一次性形态,需要用 systemd 或 nohup 补一层托管。保活不等于自动恢复,客户端重新连上后要确认拿到的是同一个会话标识、同一个工作目录,而不是新起了一个空会话。

工作目录的挂载与读写权限设置

接入后只能看不能写,通常出在三个地方:账号不在目录所属组、目录缺少组写权限位、路径上层某一级没有执行权限。先在远端把这三项查清楚,再改权限。

远端跑一个 CodeMote 常驻会话、本地按需接入同一工作目录
id                        # 当前 uid、gid 与附加组
ls -ld /srv/work          # 目录归属与权限位
stat -c '%U:%G %a %n' /srv/work
namei -l /srv/work        # 逐级检查路径权限

多人共用同一目录时,一个比较省事的做法是建一个共享组,把目录组设为该组并开启 setgid,让新文件自动继承目录组:

sudo groupadd codework
sudo usermod -aG codework alice
sudo usermod -aG codework bob
sudo chgrp -R codework /srv/work
sudo chmod 2775 /srv/work
find /srv/work -type d -exec chmod 2775 {} +
umask 0002

改完让接入账号重新登录一次再验证,附加组变更不会自动对已有会话生效。常见报错可以先这样区分:Permission denied 多为权限位或组不匹配;Read-only file system 属于挂载层面只读,用 mount | grep 挂载点 或 findmnt -T /srv/work 确认挂载参数;Operation not permitted 在容器、绑定挂载场景里偏常见,需要结合宿主目录映射和 noexec、ro 参数确认。具体改法要与实际挂载方式一起看,不要把权限位当成唯一解释。

两台设备同时接入时的文件冲突观察

不要假定 CodeMote 或底层编辑器会自动合并两端写入。用一个临时文件走一遍固定流程,把实际行为记录下来,再决定是否允许两端同时写。

  1. 设备 A 在工作目录下新建 conflict-test.txt,写入可识别内容,记下 md5sum 与 stat -c %y 的修改时间。
  2. 设备 B 接入同一目录,确认能看到该文件;看不到就先排查两端是否挂载到了不同路径。
  3. 设备 A 修改第一行并保存;设备 B 不刷新,直接修改同一行并保存。
  4. 回到设备 A 查看内容,对比 md5sum、修改时间,并检查目录里是否多出 .conflict、.bak、~ 结尾的副本文件。
  5. 交换顺序再走一次(B 先改、A 后改),确认两种顺序的结果是否对称。

把观察结果填进下面的记录表,判断依据是实际现象,不是推测:

远端跑一个 CodeMote 常驻会话、本地按需接入同一工作目录
行为类型        观察到的现象                      后续处理
后写覆盖        内容变成后写方版本,mtime 更新     约定同一文件同一时间只允许一端写
生成副本        目录里出现额外文件                 收工后统一清理并与原文件比对
写入被拒        报错或提示只读                     回查锁文件、权限位与挂载参数
部分内容丢失    文件还在但段落变少                 立即停写,用版本库或快照恢复

验证时以 md5sum 和修改时间为准,不要只看编辑器里的显示状态,缓存刷新会造成误判。两端写入频繁的场景,可以先采用一端常驻写入、另一端只读接入的方式,等确认行为后再放开。

远端重启后会话恢复与目录状态确认

远端重启后,会话不一定自动回来,工作目录也可能因为挂载顺序没挂上而变成空目录。重启前先留好核对依据,重启后逐项确认。

重启前:记录 tmux ls 与 systemctl `--user` list-units 的输出,保存一份文件清单到工作目录之外,并在目录内放一个标记文件。

远端跑一个 CodeMote 常驻会话、本地按需接入同一工作目录
find /srv/work -type f | sort > /root/work-filelist.txt
findmnt -T /srv/work
touch /srv/work/.restart-marker

重启后按顺序核对:

tmux ls
ps -eo pid,etime,cmd | grep -i codemote
findmnt -T /srv/work
ls -ld /srv/work
find /srv/work -type f -newer /srv/work/.restart-marker
diff <(cd /srv/work && find . -type f | sort) /root/work-filelist.txt

检查要点:会话是否回到了原来的工作目录而不是 /;挂载点是否就位、目录里文件数量是否与清单一致;标记文件附近是否出现重启后被改动的文件,这类文件需要人工确认是否写入完整。如果没有清单,至少用 ls -la 看目录大小与时间分布是否异常。会话恢复后先做一次只读操作验证连通,再开始写入,避免在半挂载状态下改文件。

什么任务适合常驻、什么任务用一次性会话

常驻不是默认选项,按运行时长、资源占用、数据敏感度三个维度判断,边界会比较清楚。

  • 运行时长:需要反复接入、会话之间要保留上下文(比如已建立的索引、编译缓存、正在跑的长任务)的场景适合常驻;跑一次就靠产物交付的任务,用一次性会话更省事,也少一个需要保活的进程。
  • 资源占用:常驻会话会长期占内存、文件句柄,还会一直占着工作目录里的锁文件和临时文件。多人共用一台机器或资源紧张时,宁可每次拉起。
  • 数据敏感度:工作目录里有密钥、凭据或客户数据时,常驻会话相当于长期开着一个入口,需要确认登录方式、端口暴露范围和访问日志;这些做不到,就改用一次性会话,用完即停。

可以先从常驻开始,但在会话日志里记录每次接入的设备标识与起止时间。一旦发现两端写入频率高、或者冲突测试里出现过覆盖,就改成单端写入加只读接入,或者按时间片轮流接入,把判断依据留在日志里,后面排查会省很多事。