如何恢复/var 下所有文件的默认组/用户所有权?

sep*_*ehr 13 permissions chown

我不小心将/var所有者/组更改为我的用户名,然后将其更改回 root,但并非所有/var文件夹的所有者都是 root,那么无论如何将所有者/文件/文件夹组更改回默认状态?或者至少那些由包创建的文件/文件夹?

cas*_*cas 11

最简单(也可能是最正确的)答案是“你不能”,但如果你想尝试,这里有一个 bash 脚本,它将修复 /var 下属于 .deb 包的文件的权限。

笔记:

  • 它不会修复不属于包的文件的权限。
  • 它不会修复软件包不再可供 apt-get 下载的文件的权限 - 例如遗留或第三方软件包。
  • AFAIK,debian 包中没有文件在文件名中包含制表符,所以我使用 TAB 作为 IFS 用于 while-read 循环。我已经检查了 debian sid 的 Contents-amd64.gz 和 Contents-i386.gz 并确认没有选项卡,但第三方软件包可能有一些。

该脚本通过生成在 var 中有文件的已安装包列表,下载这些包,然后使用它dpkg-deb -c来找出权限应该是什么。

最难的部分是编写函数以将权限字符串(如ls -l或显示的tar v)转换为八进制数字模式,包括满足 setuid、setgid 和粘滞位的需求......一些使用不错的算法很容易编写的东西比如说,perl 在 bash 中太麻烦了,所以暴力破解它更容易。

最后,脚本被编写为处于“调试模式”或“试运行”模式。要使其实际更改所有者/组/权限,请注释掉或删除带有__EOF__此处文档标记的两行。

#! /bin/bash

perm_string_to_mode() {
  string="$1"
  let perms=0

  [[ "${string}" = ?r???????? ]] && perms=$(( perms +  400 ))
  [[ "${string}" = ??w??????? ]] && perms=$(( perms +  200 ))
  [[ "${string}" = ???x?????? ]] && perms=$(( perms +  100 ))
  [[ "${string}" = ???s?????? ]] && perms=$(( perms + 4100 ))
  [[ "${string}" = ???S?????? ]] && perms=$(( perms + 4000 ))
  [[ "${string}" = ????r????? ]] && perms=$(( perms +   40 ))
  [[ "${string}" = ?????w???? ]] && perms=$(( perms +   20 ))
  [[ "${string}" = ??????x??? ]] && perms=$(( perms +   10 ))
  [[ "${string}" = ??????s??? ]] && perms=$(( perms + 2010 ))
  [[ "${string}" = ??????S??? ]] && perms=$(( perms + 2000 ))
  [[ "${string}" = ???????r?? ]] && perms=$(( perms +    4 ))
  [[ "${string}" = ????????w? ]] && perms=$(( perms +    2 ))
  [[ "${string}" = ?????????x ]] && perms=$(( perms +    1 ))
  [[ "${string}" = ?????????t ]] && perms=$(( perms + 1001 ))
  [[ "${string}" = ?????????T ]] && perms=$(( perms + 1000 ))

  echo $perms
}

# generate a list of installed packages that have files etc in /var
grep -l /var/ /var/lib/dpkg/info/*.list  | \
  sed -e 's:/var/lib/dpkg/info/::' -e 's/\.list$//' | \
  xargs dpkg -l | \
  awk '/^[hi]/ {print $2}' > /tmp/packages.list

# clean out the apt cache, so we only have one version of each package
apt-get clean

# download the packages as if we were going to reinstall them
# NOTE: packages which are no longer available for download
# will not have their permissions fixed.  apt-get will complain about
# those packages, so you can get a list by redirecting or tee-ing the
# output of this script.
xargs apt-get -y -d -u --reinstall install < /tmp/packages.list

for pkg in $(cat /tmp/packages.list) ; do
   PKGFILE="/var/cache/apt/archives/${pkg}_*.deb"

   if [ -e $PKGFILE ] ; then

     dpkg-deb -c /var/cache/apt/archives/${pkg}_*.deb | \
       awk '/\.\/var\// {print $1, $2, $6}' | \
       sed -e 's/ /\t/' -e 's/ /\t' | \
       while IFS=$'\t' read permstring ownergroup filename ; do
          # don't change owner/group/perms on symlinks
          if ! [[ "${permstring}" =~ ^l ]] ; then
            mode=$(perm_string_to_mode $permstring)
            # change "owner/group" to "owner:group" for chown
            ownergroup=${ownergroup//\//:}
            # remove leading '.' from filename
            filename=${filename#?}
cat <<__EOF__
            chown "$ownergroup" "$filename"
            chmod "$mode" "$filename"
__EOF__ 
         fi
       done
     echo
   fi
done
Run Code Online (Sandbox Code Playgroud)

当然,该脚本可以很容易地修改以修复任何其他目录或所有目录中的打包文件权限。

如果 $packagename.list 文件中的 $packagename.list 文件/var/lib/dpkg/info具有所有者、组和八进制权限以及文件名,则此脚本会简单得多……但它们没有。


小智 6

与上述答案之一类似,如果您在本地目录中有名为“var”的正确权限的目录副本,则可以使用以下两个命令恢复对 /var 目录的权限。

sudo find var -exec chown --reference="{}" "/{}" \;
sudo find var -exec chmod --reference="{}" "/{}" \;
Run Code Online (Sandbox Code Playgroud)