Jawaban paling sederhana (dan mungkin paling benar) adalah "Anda tidak bisa", tetapi jika Anda ingin mencoba, inilah skrip bash yang akan memperbaiki izin file di bawah / var milik paket .deb.
CATATAN:
- itu tidak akan memperbaiki perms untuk file yang bukan milik paket.
- itu tidak akan memperbaiki perms untuk file di mana paket tidak lagi tersedia untuk diunduh oleh apt-get - mis. paket legacy atau pihak ketiga.
- AFAIK, tidak ada file dalam paket debian memiliki tab di nama file, jadi saya telah menggunakan TAB sebagai IFS untuk loop sambil membaca. Saya telah memeriksa Contents-amd64.gz dan Contents-i386.gz untuk debian sid dan mengkonfirmasi bahwa tidak ada tab, tetapi paket pihak ketiga mungkin memiliki beberapa.
Script bekerja dengan menghasilkan daftar paket yang diinstal yang memiliki file dalam var, mengunduh paket-paket itu, dan kemudian menggunakan dpkg-deb -c
untuk mencari tahu apa yang seharusnya menjadi izin.
Bagian tersulit adalah menulis fungsi untuk mengubah string izin (seperti yang ditampilkan oleh ls -l
atau tar v
) ke mode numerik oktal, termasuk katering untuk setuid, setgid, dan bit lengket .... beberapa hal yang akan mudah ditulis dengan algoritma yang bagus di, katakanlah, perl terlalu banyak kesulitan dalam bash, jadi lebih mudah untuk hanya memaksa saja.
Akhirnya, skrip ditulis dalam mode "debug-mode" atau "dry-run". Untuk membuatnya benar-benar mengubah pemilik / grup / perm, komentar-keluar atau hapus dua baris dengan __EOF__
penanda dokumen di sini.
#! /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
Script, tentu saja, dapat dengan mudah diadaptasi untuk memperbaiki perm-file yang dikemas dalam direktori lain, atau di semua direktori.
Script ini akan jauh lebih mudah jika file $ packagename.list di /var/lib/dpkg/info
memiliki perm, group, dan oktal perms serta nama file ... tetapi tidak.
chown
perintah? dan akan ditutup.