由于实验室的英伟达DGX Station服务器多年无人管理,经过数年后apt升级屡屡报错。于是需要重装最新的DGX OS,即魔改版Ubuntu。但是直接重装会使得所有用户需要重新建立账户。于是我开始寻找如何最大化无感升级系统,在重装后直接使用原先的账户密码登录服务器。

Linux系统与用户账户有关的文件

Linux系统通过四个文件来管理用户账户,它们都位于/etc目录,分别是:

  • passwd:这个文件虽然名叫密码,但是里面不存储直接与密码相关的信息。它规定了一个用户的名字、UID、所属组、家目录、启动shell等信息;

  • group:这个文件的用处与名字相符,主要规定了用户组的信息,包括组名、GID、组中的用户等;

  • shadow:顾名思义,这个文件中存储的是用户的”影子“,即密码的哈希;

  • gshadow:同样顾名思义,这个文件中存储的是用户组的”影子“,即用户组密码的哈希,即使我们不经常为用户组设置密码。所以可以看到其中除了用户组名,其他信息基本都为空。

通过备份还原这些文件,即可恢复用户账户。但是其中有许多特殊账户需要注意:

  • sudo用户组是具有管理员权限的组,任何用户一旦加入这个组即可借助sudo拥有管理员权限。需要保留这个组。

  • UIDGID小于1000(不包含)的是系统内建的用户和组。这部分组不建议备份还原,因为不同系统可能有不同的约定和不同的软件。

  • 有一些系统内建的组包含了某些用户。这部分可以选择性还原。但不还原也没有影响。可以在安装新软件的过程中让软件自动设置。

所以,这部分的最佳实践为:备份以上四个文件到私人电脑,删除无用的用户和组。删后需核对四个文件的行数,passwdgroup文件的行数应一致,并且比shadwogshadow文件少一行(sudo用户组)。

备份与还原/home目录

想要做到无损重装系统,用户文件也需要备份和还原。一般来说用户只会在自己的家目录工作,所以备份/home目录下的文件已经足够。

使用如下命令来使用tar文件备份整个家目录:

sudo tar -cvpf backup.tar /home

如需使用gzip压缩,使用:

sudo tar -cvpzf backup.tar.gz /home

在备份之后,使用scp拷贝至另一台电脑或者使用移动硬盘备份均可。

注意,我们使用了-p选项。该选项可以保留文件权限。这样还原之后还是属于原来的用户,而不是root

还原/home目录时,建议不要直接覆盖家目录,而是复制到一个目录中,再拷贝所有用户家目录至新系统的家目录,以防止数据丢失,命令分别为:

sudo tar -xvpf backup.tar -C ~/backup
sudo tar -xvpzf backup.tar.gz -C ~/backup

注意,这里的-C选项指定解压缩的目标目录.

还原文件所有者

如果在上一步没有使用-p选项,那么解压后所有文件的所有者会全部变为root。这时可以用脚本将对应目录中的文件所有者全部改为该用户:

# 遍历 /home 目录下的所有文件夹
for user_dir in /home/*; do
  # 获取文件夹的名称,即用户名
  user=$(basename "$user_dir")

  # 确保用户名对应的用户和组存在
  if id -u "$user" > /dev/null 2>&1; then
    # 确保该目录不是软链接
    if [ -d "$user_dir" ]; then
      # 将文件夹及其内容的所有者和组改为用户名
      sudo chown -R --no-dereference "$user:$user" "$user_dir"
    else
      echo "注意:$user_dir 是一个软链接,跳过该目录"
    fi
  else
    echo "用户 $user 不存在,跳过该目录"
  fi
done