#!/bin/sh set -e Version="20061205-1" NomProg=$(basename $0) ArchTmp="" OpcDesfrag='no' OpcMinFrag=2 muestraAyuda() { cat <&2 exit 10 fi eval set -- "$TEMP" while true; do case "$1" in -h|--help) muestraAyuda; exit 0;; -d|--desfrag) OpcDesfrag="si"; shift;; -f|--min-frag) OpcMinFrag="$2"; shift 2;; --) shift; break;; *) echo "ERROR: no se pudo parsear las opciones." >&2; exit 12;; esac done if [ "$*" != "" ]; then echo "ERROR: no se reconocen estos argumentos: $*." >&2 exit 14 fi if ! [ "$OpcMinFrag" -ge "2" ] 2>/dev/null; then echo "ERROR: -f o --min-frag debe ser igual a 2 o mayor." >&2 exit 16 fi finalizacion() { if [ "$ArchTmp" != "" -a -f "$ArchTmp" ]; then rm -f "$ArchTmp" || true fi echo PorcArchFragAntes=$(echo "scale=1; ($ArchFragAntes*100) / $CantArch" | bc) PorcArchFragDesp=$(echo "scale=1; ($ArchFragDesp*100) / $CantArch" | bc) FragPorArchAntes=$(echo "scale=3; $TotalFragAntes/$CantArch" | bc) FragPorArchDesp=$(echo "scale=3; $TotalFragDesp/$CantArch" | bc) echo "$CantArch archivos procesados, $TamTotal bytes, fragmentados antes $ArchFragAntes ($PorcArchFragAntes%) y despues $ArchFragDesp ($PorcArchFragDesp%), fragmentos promedio por archivo antes $FragPorArchAntes y despues $FragPorArchDesp." trap - HUP INT QUIT ABRT TERM EXIT exit } trap finalizacion HUP INT QUIT ABRT TERM EXIT CantArch=0 TamTotal=0 ArchFragAntes=0 ArchFragDesp=0 TotalFragAntes=0 TotalFragDesp=0 IFSInicial="$IFS" IFSLinea=' ' export IFS="$IFSLinea" for ArchYFrag in $(find -xdev -type f -exec filefrag '{}' \+ | \ sed -r 's/(.*): ([^: ]+)([^:])+$/\2:\1/' | sort -n -r) do IFS="$IFSInicial" Arch=${ArchYFrag#*:} Frag=${ArchYFrag%%:*} Tam=$(stat -c '%s' "$Arch") echo -n "$Arch: $Frag fragmentos, $Tam bytes" CantArch=$(($CantArch + 1)) TamTotal=$(($TamTotal + $Tam)) Desfragmentar="$OpcDesfrag" TotalFragAntes=$(($TotalFragAntes + $Frag)) if [ "$Frag" -ge "$OpcMinFrag" ]; then ArchFragAntes=$(($ArchFragAntes + 1)) EstabaFragmentado='si' else echo -n ", ya esta desfragmentado" Desfragmentar='no' EstabaFragmentado='no' fi if [ "$Desfragmentar" = 'si' ]; then Enlaces=$(stat -c '%h' "$Arch") if [ "$Enlaces" != '1' ]; then echo -n ", imposible desfragmentar porque tiene $Enlaces enlaces duros" Desfragmentar='no' fi fi OriginalConservado="si" if [ "$Desfragmentar" = 'si' ]; then ArchTmp="$Arch.$NomProg.$$.tmp" if cp -a "$Arch" "$ArchTmp"; then FragDesp=$(filefrag "$ArchTmp") FragDesp=${FragDesp##*: } FragDesp=${FragDesp%% extent*} echo -n ", $FragDesp fragmentos luego" if [ "$FragDesp" -lt "$Frag" ]; then if mv "$ArchTmp" "$Arch"; then TotalFragDesp=$(($TotalFragDesp + $FragDesp)) if [ "$FragDesp" -ge "$OpcMinFrag" ]; then echo -n ", sigue fragmentado" ArchFragDesp=$(($ArchFragDesp + 1)) else echo -n ", desfragmentado" fi OriginalConservado="no" else echo -n ", no se pudo renombrar la nueva copia (esto NO es normal y puede ser peligroso!!!), se conserva el original" fi else echo -n ", se conserva el original" fi else echo -n ", no se pudo copiar, se conserva el original" fi rm "$ArchTmp" 2>/dev/null || true fi if [ "$OriginalConservado" = 'si' ]; then TotalFragDesp=$(($TotalFragDesp + $Frag)) if [ "$EstabaFragmentado" = 'si' ]; then ArchFragDesp=$(($ArchFragDesp + 1)) fi fi echo "." done