Câu trả lời đơn giản nhất (và có lẽ đúng nhất) là "Bạn không thể", nhưng nếu bạn muốn thử, đây là một tập lệnh bash sẽ sửa các quyền của các tệp trong / var thuộc các gói .deb.
GHI CHÚ:
- nó sẽ không sửa chữa perms cho các tập tin không thuộc một gói.
- nó sẽ không sửa lỗi cho các tệp trong đó gói không còn có sẵn để tải xuống bởi apt-get - ví dụ: gói cũ hoặc gói của bên thứ ba.
- AFAIK, không có tệp nào trong các gói debian có các tab trong tên tệp, vì vậy tôi đã sử dụng TAB làm IFS cho vòng lặp while-read. Tôi đã kiểm tra Nội dung-amd64.gz và Nội dung-i386.gz cho bên debian và xác nhận rằng không có tab nào, nhưng các gói của bên thứ ba có thể có một số.
Kịch bản hoạt động bằng cách tạo danh sách các gói đã cài đặt có tệp var, tải xuống các gói đó và sau đó sử dụng dpkg-deb -c
để tìm hiểu các quyền nên là gì.
Phần khó nhất là viết hàm để chuyển đổi chuỗi quyền (như được hiển thị bởi ls -l
hoặc tar v
) sang chế độ số bát phân, bao gồm phục vụ cho setuid, setgid và bit dính .... một số điều có thể dễ dàng viết bằng thuật toán đẹp giả sử, perl có quá nhiều rắc rối trong bash, vì vậy việc vũ trang nó trở nên dễ dàng hơn.
Cuối cùng, tập lệnh được viết ở chế độ "gỡ lỗi" hoặc "chạy khô". Để làm cho nó thực sự thay đổi chủ sở hữu / nhóm / perms, hãy bình luận hoặc xóa hai dòng bằng các __EOF__
đánh dấu tài liệu ở đây trên chúng.
#! /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
Tất nhiên, tập lệnh có thể được điều chỉnh khá dễ dàng để sửa lỗi perm-file được đóng gói trong bất kỳ thư mục nào khác, hoặc trong tất cả các thư mục.
Kịch bản này sẽ đơn giản hơn rất nhiều nếu các tệp $ packagename.list /var/lib/dpkg/info
có chủ sở hữu, nhóm và bát phân cũng như tên tệp ... nhưng chúng không có.
chown
lệnh? và đã bị đóng cửa.