把 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 补一层托管。保活不等于自动恢复,客户端重新连上后要确认拿到的是同一个会话标识、同一个工作目录,而不是新起了一个空会话。
工作目录的挂载与读写权限设置
接入后只能看不能写,通常出在三个地方:账号不在目录所属组、目录缺少组写权限位、路径上层某一级没有执行权限。先在远端把这三项查清楚,再改权限。
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 或底层编辑器会自动合并两端写入。用一个临时文件走一遍固定流程,把实际行为记录下来,再决定是否允许两端同时写。
- 设备 A 在工作目录下新建 conflict-test.txt,写入可识别内容,记下 md5sum 与 stat -c %y 的修改时间。
- 设备 B 接入同一目录,确认能看到该文件;看不到就先排查两端是否挂载到了不同路径。
- 设备 A 修改第一行并保存;设备 B 不刷新,直接修改同一行并保存。
- 回到设备 A 查看内容,对比 md5sum、修改时间,并检查目录里是否多出 .conflict、.bak、~ 结尾的副本文件。
- 交换顺序再走一次(B 先改、A 后改),确认两种顺序的结果是否对称。
把观察结果填进下面的记录表,判断依据是实际现象,不是推测:
行为类型 观察到的现象 后续处理
后写覆盖 内容变成后写方版本,mtime 更新 约定同一文件同一时间只允许一端写
生成副本 目录里出现额外文件 收工后统一清理并与原文件比对
写入被拒 报错或提示只读 回查锁文件、权限位与挂载参数
部分内容丢失 文件还在但段落变少 立即停写,用版本库或快照恢复
验证时以 md5sum 和修改时间为准,不要只看编辑器里的显示状态,缓存刷新会造成误判。两端写入频繁的场景,可以先采用一端常驻写入、另一端只读接入的方式,等确认行为后再放开。
远端重启后会话恢复与目录状态确认
远端重启后,会话不一定自动回来,工作目录也可能因为挂载顺序没挂上而变成空目录。重启前先留好核对依据,重启后逐项确认。
重启前:记录 tmux ls 与 systemctl `--user` list-units 的输出,保存一份文件清单到工作目录之外,并在目录内放一个标记文件。
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 看目录大小与时间分布是否异常。会话恢复后先做一次只读操作验证连通,再开始写入,避免在半挂载状态下改文件。
什么任务适合常驻、什么任务用一次性会话
常驻不是默认选项,按运行时长、资源占用、数据敏感度三个维度判断,边界会比较清楚。
- 运行时长:需要反复接入、会话之间要保留上下文(比如已建立的索引、编译缓存、正在跑的长任务)的场景适合常驻;跑一次就靠产物交付的任务,用一次性会话更省事,也少一个需要保活的进程。
- 资源占用:常驻会话会长期占内存、文件句柄,还会一直占着工作目录里的锁文件和临时文件。多人共用一台机器或资源紧张时,宁可每次拉起。
- 数据敏感度:工作目录里有密钥、凭据或客户数据时,常驻会话相当于长期开着一个入口,需要确认登录方式、端口暴露范围和访问日志;这些做不到,就改用一次性会话,用完即停。
可以先从常驻开始,但在会话日志里记录每次接入的设备标识与起止时间。一旦发现两端写入频率高、或者冲突测试里出现过覆盖,就改成单端写入加只读接入,或者按时间片轮流接入,把判断依据留在日志里,后面排查会省很多事。