Al trabajar con entornos Python en sistemas operativos como Fedora, es posible que ocurran situaciones donde los entornos virtuales no funcionen como se espera debido a problemas de configuración o cambios en el sistema. Si accidentalmente se instalan paquetes de pip en el entorno global del sistema en lugar de en un entorno virtual, puede surgir la necesidad de eliminarlos. Sin embargo, la desinstalación directa puede fallar, especialmente si los paquetes fueron instalados por el gestor de paquetes del sistema (como rpm) o si faltan archivos de registro de instalación.
Un intento típico de exportar e desinstalar usando pip freeze y pip uninstall -r puede resultar en errores como:
$ pip uninstall -r /tmp/uninstall_pip.txt
Found existing installation: anyio 4.11.0
error: uninstall-no-record-file
× Cannot uninstall anyio 4.11.0
╰─> The package's contents are unknown: no RECORD file was found for anyio.
hint: The package was installed by rpm. You should check if it can uninstall the package.
Estos errores indican que pip no puede gestionar la desinstalación porque el paquete no fue instalado a través de pip de la manera habitual, o por problemas de permisos. Ignorar estos errores y forzar la desinstalación de todos los paquetes listados puede ser una solución, pero conlleva riesgos significativos.
A continuación, se presenta un script de shell diseñado para intentar desinstalar todos los pqauetes de pip disponibles, omitiendo aquellos que generen errores durante el proceso. Esto permite eliminar la mayoría de los paquetes instalados por error mientras se evitan fallos críticos causados por paquetes gestionados por el sistema.
#!/bin/bash
# forceful_cleanup.sh - Script para una limpieza agresiva de paquetes pip
echo "🚀 Iniciando limpieza agresiva de paquetes pip..."
echo "Generando lista de paquetes..."
# Obtiene todos los nombres de paquetes instalados
python3 -m pip list --format=freeze | cut -d'=' -f1 > /tmp/all_packages_to_remove.txt
echo "Se procesarán un total de $(wc -l < /tmp/all_packages_to_remove.txt) paquetes."
# Intenta desinstalar cada paquete, saltando los que fallen
successful_uninstalls=0
failed_uninstalls=0
packages_skipped=()
while IFS= read -r package_name; do
echo "Intentando desinstalar: $package_name"
# Intenta desinstalar sin mostrar errores de pip, redirigiendo stderr a /dev/null
if python3 -m pip uninstall -y "$package_name" &> /dev/null; then
echo " ✅ Desinstalación exitosa: $package_name"
((successful_uninstalls++))
else
echo " ❌ Fallo al desinstalar: $package_name (posiblemente paquete del sistema o problema de permisos)"
packages_skipped+=("$package_name")
((failed_uninstalls++))
fi
done < /tmp/all_packages_to_remove.txt
echo ""
echo "=== Proceso de limpieza finalizado ==="
echo "✅ Paquetes desinstalados con éxito: $successful_uninstalls"
echo "❌ Paquetes omitidos: $failed_uninstalls"
echo ""
if [ ${#packages_skipped[@]} -gt 0 ]; then
echo "Lista de paquetes omitidos:"
for pkg in "${packages_skipped[@]}"; do
echo " - $pkg"
done
fi
# Limpieza temporal de archivos
rm -f /tmp/all_packages_to_remove.txt
La ejecución de este script puede producir una salida similar a:
Intentando desinstalar: zstandard
❌ Fallo al desinstalar: zstandard (posiblemente paquete del sistema o problema de permisos)
=== Proceso de limpieza finalizado ===
✅ Paquetes desinstalados con éxito: 0
❌ Paquetes omitidos: 151
Lista de paquetes omitidos:
- anyio
- apsw
- argcomplete
Advertencia: Este método es agresivo y puede eliminar paquetes esencialse si se ejecuta en un entorno del sistema no deseado. Úselo con extrema precaución y solo si comprende completamente las implicaciones.