最稳妥方式是用 usermod -d -m 一步迁移家目录,需确保用户未登录、目标路径已存在且权限正确;手动迁移则必须用 rsync -av --delete 并及时修正属主与 selinux 上下文。

usermod 是最稳妥的修改方式,但必须确保用户未登录、目标路径已存在且权限正确,否则会静默失败或破坏登录环境。
用 usermod -d -m 一步迁移家目录
这是官方推荐做法,usermod 会自动处理路径更新和文件移动,避免手动编辑 /etc/passwd 出错。
操作前确认:
-
testuser当前没有活跃登录会话(可用loginctl list-users或who检查) - 目标路径
/data/users/testuser已创建,且属主为 root(usermod会自动改属主) - 磁盘空间足够:
df -h /data
执行命令:
sudo usermod -d /data/users/testuser -m testuser
注意:-m 表示移动旧内容,-d 指定新路径;顺序不能颠倒,且中间不能有空格。执行后 /home/testuser 会被清空(但目录本身保留),$HOME 环境变量在下次登录时自动生效。
手动迁移时 rsync 参数不能少 -a 和 --delete
如果因特殊原因必须手动迁移(比如跨文件系统、需保留原目录做灰度验证),rsync 是唯一可靠选择。
错误写法:cp -r /home/testuser /data/users/ —— 会丢失符号链接、ACL、扩展属性、硬链接关系,且无法增量同步。
正确写法:
sudo rsync -av --delete --progress /home/testuser/ /data/users/testuser/
关键点:
- 源路径末尾带
/:表示同步目录“内容”,而非整个目录名 -
-a=-rlptgoD,保留所有元数据 -
--delete:确保目标与源完全一致(避免残留旧配置干扰) - 务必在
chown前完成同步,否则rsync可能因权限拒绝复制隐藏文件(如.bashrc)
修改 /etc/passwd 后必须立刻 chown,否则登录报错 Could not chdir to home directory
即使 vipw 成功改了 /etc/passwd 中的字段,若新目录所有权仍是 root:root,用户登录时 shell 会直接退出,并在 /var/log/auth.log 记录该错误。
修复步骤:
- 确认新路径归属:
ls -ld /data/users/testuser - 递归修正:
sudo chown -R testuser:testuser /data/users/testuser - 设置最小权限:
sudo chmod 700 /data/users/testuser(尤其防止其他用户读取.ssh或.gnupg)
特别注意:chown -R 必须在用户首次登录前完成;如果已失败登录过,可能生成了临时 ~/.Xauthority 等文件,属主错误,需一并修正。
验证环节最容易漏掉 su - testuser -c 'echo $HOME'
不要只依赖图形界面登录测试——很多桌面环境会缓存旧路径或 fallback 到 /tmp,掩盖问题。
真实验证应分三步:
- 切换用户并打印变量:
sudo su - testuser -c 'echo $HOME; ls -A | head -5' - 检查关键配置文件是否可读:
sudo su - testuser -c 'ls -l ~/.bashrc ~/.profile 2>/dev/null || echo "missing config" - 运行交互式 shell:
sudo su - testuser,输入pwd和ls -la确认上下文无异常
如果 su - 报错 No directory, logging in with HOME=/,说明 /etc/passwd 路径写错、目录不存在或权限不足,需回退检查前三步。
实际迁移中,最常被跳过的其实是磁盘配额和 SELinux 上下文——如果你启用了 setquota 或 sestatus 为 enforcing,新路径需要重新打标(sudo semanage fcontext -a -t home_root_t "/data/users(/.*)?")或分配配额,否则用户可能无法写入。











