La respuesta más simple (y probablemente la más correcta) es "No puedes", pero si quieres probar, aquí hay un script bash que arreglará los permisos de los archivos bajo / var que pertenecen a paquetes .deb.
NOTAS
- no arreglará permisos para archivos que no pertenecen a un paquete.
- no arreglará permisos para archivos donde el paquete ya no esté disponible para su descarga por apt-get, por ejemplo, paquetes heredados o de terceros.
- AFAIK, ningún archivo en los paquetes de Debian tiene pestañas en el nombre del archivo, así que he usado TAB como IFS para el ciclo while-read. He comprobado los Contenidos-amd64.gz y Contenidos-i386.gz para debian sid y he confirmado que no hay pestañas, pero los paquetes de terceros pueden tener algunos.
El script funciona generando una lista de paquetes instalados que tienen archivos en var, descargando esos paquetes y luego usándolos dpkg-deb -c
para averiguar cuáles deberían ser los permisos.
La parte más difícil fue escribir la función para convertir la cadena de permisos (como se muestra por ls -l
o tar v
) a un modo numérico octal, que incluye ajustes para setuid, setgid y bits fijos ... algunas cosas que serían fáciles de escribir con un buen algoritmo en, digamos, perl son demasiados problemas en bash, por lo que es más fácil simplemente forzarlo.
Finalmente, el script está escrito para estar en modo "debug-mode" o "dry-run". Para que realmente cambie el propietario / grupo / permisos, comente o elimine las dos líneas con los __EOF__
marcadores de documento aquí.
#! /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
La secuencia de comandos podría, por supuesto, adaptarse fácilmente para corregir los permisos de archivos empaquetados en cualquier otro directorio, o en todos los directorios.
Esta secuencia de comandos habría sido mucho más simple si los archivos $ packagename.list en el /var/lib/dpkg/info
propietario, grupo y permisos octales, así como el nombre de archivo ... pero no lo hacen.
chown
comando? y hubiera sido cerrado