Apt cache aufraeumen: Unterschied zwischen den Versionen

Aus Linupedia.org
Wechseln zu: Navigation, Suche
K
K (TomcatMJ verschob Seite Apt cache aufräumen nach Apt cache aufraeumen: Umlautsalat korrigiert)
 
(2 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 411: Zeile 411:
  
 
----
 
----
[[Shellscripte|Zurück zur Shellscripte Übersicht]]<br />
+
[[Quellcodes|Zurück zur Quellcodes-Übersicht]]<br />
[[APT|Zurück zur Apt und Smart Übersicht]]<br/>  
+
[[Paketmanager|Zurück zum Paketmanager]]<br/>  
 
[[Category:APT]]
 
[[Category:APT]]
[[Category:Scripte]]
+
[[Category:Quellcodes]]

Aktuelle Version vom 20. November 2013, 20:25 Uhr

hier mal ein kleines Tool um den apt cache (normalerweise /var/cache/apt/*) etwas aufzuräumen.

Es ist eine Kombination aus einem Python-Script und einem kleinen C-Programm zum Versionsvergleich. Ich habe diese beiden Tools einfach mal kombiniert :)

Teil 1: Python Script apt-smartclean.py

#! /usr/bin/python 
#  GPL v2 code. Radim Kolar <hsn/at/cybermail.net> 
#  http://home.tiscali.cz/~cz210552/ 
#  modified for rpm Distris by oc2pus 
# 
#  APT-SMARTCLEAN 
# 
#  This programs cleans APT package cache directory. Unlike apt-get autoclean, 
#  it leaves in cache directory only last version of package even if this 
#  package is no longer available for download. This is less aggressive 
#  cleaning than autoclean does. 
# 
#  ARGUMENTS -s  ... dry run 
# 
#  Changelog 
# 
#    VERSION 1 - 18 Aug 2003 First version 
#    VERSION 1.1 - 14 Dec 2004 modifications for rpm based distris 

import os 
import sys 

def cleanaptcache(dryrun=0,dirs=('/var/cache/apt/archives/','/var/cache/apt/archives/partial/')): 
    for dir in dirs: 
       packages={} # versions 
       fnames={}   # file names 
       for file in os.listdir(dir): 
     if file[-4:] != '.rpm': continue 
     parsed=file.split('_') 
     if len(parsed) != 3: continue 
     parsed[1]=parsed[1].replace('%3a',':') 
     if packages.has_key(parsed[0]): 
         print 'Found',parsed[0],parsed[1],'have',packages[parsed[0]] 
              # 1:  a is newer than b 
              # 0:  a and b are the same version 
              # -1: b is newer than a 
              #  2: wrong arguments number         
         argz=['rvc',parsed[1],packages[parsed[0]]] 
         rc=os.spawnvp(os.P_WAIT,'./rvc',argz) 
         if rc==0: 
       print "skipping",fnames[parsed[0]] 
            continue 
         if rc==255: 
       print "\tDeleting",dir+file 
       if not dryrun: os.unlink(dir+file) 
       continue 
         elif rc==1: 
       print "\tDeleting",dir+fnames[parsed[0]] 
       if not dryrun: os.unlink(dir+fnames[parsed[0]]) 
       
     packages[parsed[0]]=parsed[1] 
     fnames[parsed[0]]=file 

if __name__=="__main__": 
    sys.stdout.write("Running on SuSE\n") 
    sys.stdout.flush() 
    if len(sys.argv)>1 and sys.argv[1]=='-s': 
   dryrun=1 
   print "Dry run is enabled. Not deleting anything." 
    else: 
   dryrun=0 
    cleanaptcache(dryrun) 

Teil 2a: C-Programm rvc.c

/* 
 * $Id: rvc.c,v 1.5 2002/10/27 18:27:23 luigi Exp $ 
 ****** 
 * rvc.c - RPM Version Compare 
 * Given two strings representing a different version and release 
 * of a single rpm package, it returns which one is newer or, 
 * alternatively, an error. 
 * 
 * parameters 
 *        two strings (a and b) structured in the following way: 
 *        <RPM_version>-<RPM_release>. 
 * 
 * return values 
 *        1: a is newer than b 
 *        0: a and b are the same version 
 *       -1: b is newer than a 
 *        2: wrong arguments number 
 * 
 * The assumption the two strings to compare are "logically coherent" 
 * is made, otherwise you will probably end up being told that b is 
 * newer than a (something which happens in this kind of situation).. 
 * The rpmvercmp function is "borrowed" from the Redhat package manager 
 * (RPM 4.1), as are all the inline functions in the header file 
 * (rpmvercmp.h). 
 * 
 ****** 
 * 
 *   Copyright 2002 Luigi Bitonti 
 *    
 *   Copyright 2002 Redhat Inc. 
 * 
 *   This file is part of rvc (RPM version compare). 
 * 
 *   rvc is free software; you can redistribute it and/or modify 
 *   it under the terms of the GNU General Public License as published by 
 *   the Free Software Foundation; either version 2 of the License, or 
 *   (at your option) any later version. 
 * 
 *   rvc is distributed in the hope that it will be useful, 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *   GNU General Public License for more details. 
 * 
 *   You should have received a copy of the GNU General Public License 
 *   along with rvc; if not, write to the Free Software 
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 * 
 */ 


#include "rvc.h" 


int 
main(int argc, char **argv) 
{ 

    /* We need exactly two arguments for the comparison */ 
    if (argc != 3) 
    { 
      fprintf(stderr, "Usage: %s <RPM_versionA>-<RPM_releaseA> <RPM_versionB>-<RPM_releaseB>", argv[0]); 
      return 2; 
    } 

    return rpmvercmp(argv[1], argv[2]);      
} 


/* compare alpha and numeric segments of two versions */ 
/* return 1: a is newer than b */ 
/*        0: a and b are the same version */ 
/*       -1: b is newer than a */ 
int 
rpmvercmp(const char * a, const char * b) 
{ 
    char oldch1, oldch2; 
    char * str1, * str2; 
    char * one, * two; 
    int rc; 
    int isnum; 

    /* easy comparison to see if versions are identical */ 
    if (!strcmp(a, b)) return 0; 

    str1 = alloca(strlen(a) + 1); 
    str2 = alloca(strlen(b) + 1); 

    strcpy(str1, a); 
    strcpy(str2, b); 

    one = str1; 
    two = str2; 

    /* loop through each version segment of str1 and str2 and compare them */ 
    while (*one && *two) 
    { 
   while (*one && !xisalnum(*one)) one++; 
   while (*two && !xisalnum(*two)) two++; 

   str1 = one; 
   str2 = two; 

   /* grab first completely alpha or completely numeric segment */ 
   /* leave one and two pointing to the start of the alpha or numeric */ 
   /* segment and walk str1 and str2 to end of segment */ 
   if (xisdigit(*str1)) 
   { 
       while (*str1 && xisdigit(*str1)) str1++; 
       while (*str2 && xisdigit(*str2)) str2++; 
       isnum = 1; 
   } else { 
       while (*str1 && xisalpha(*str1)) str1++; 
       while (*str2 && xisalpha(*str2)) str2++; 
       isnum = 0; 
   } 

   /* save character at the end of the alpha or numeric segment */ 
   /* so that they can be restored after the comparison */ 
   oldch1 = *str1; 
   *str1 = '\0'; 
   oldch2 = *str2; 
   *str2 = '\0'; 

   /* take care of the case where the two version segments are */ 
   /* different types: one numeric, the other alpha (i.e. empty) */ 
   if (one == str1) return -1;   /* arbitrary */ 
   if (two == str2) return -1; 

   if (isnum) 
   { 
       /* this used to be done by converting the digit segments */ 
       /* to ints using atoi() - it's changed because long  */ 
       /* digit segments can overflow an int - this should fix that. */ 

       /* throw away any leading zeros - it's a number, right? */ 
       while (*one == '0') one++; 
       while (*two == '0') two++; 

       /* whichever number has more digits wins */ 
       if (strlen(one) > strlen(two)) return 1; 
       if (strlen(two) > strlen(one)) return -1; 
   } 

   /* strcmp will return which one is greater - even if the two */ 
   /* segments are alpha or if they are numeric.  don't return  */ 
   /* if they are equal because there might be more segments to */ 
   /* compare */ 
   rc = strcmp(one, two); 
   if (rc < 0) 
       return -1; 
   else if (rc > 0) 
       return 1; 

   /* restore character that was replaced by null above */ 
   *str1 = oldch1; 
   one = str1; 
   *str2 = oldch2; 
   two = str2; 
    } 

    /* this catches the case where all numeric and alpha segments have */ 
    /* compared identically but the segment sepparating characters were */ 
    /* different */ 
    if ((!*one) && (!*two)) return 0; 

    /* whichever version still has characters left over wins */ 
    if (!*one) return -1; else return 1; 
} 

Teil 2b: rvc.h

/* 
 * $Id: rvc.h,v 1.4 2002/10/27 18:28:00 luigi Exp $ 
 ** 
 * rvc.h - include file for rvc.c 
 * 
 *   Copyright 2002 Luigi Bitonti 
 *    
 *   Copyright 2002 Redhat Inc. 
 * 
 *   This file is part of rvc (RPM version compare). 
 * 
 *   rvc is free software; you can redistribute it and/or modify 
 *   it under the terms of the GNU General Public License as published by 
 *   the Free Software Foundation; either version 2 of the License, or 
 *   (at your option) any later version. 
 * 
 *   rvc is distributed in the hope that it will be useful, 
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *   GNU General Public License for more details. 
 * 
 *   You should have received a copy of the GNU General Public License 
 *   along with rvc; if not, write to the Free Software 
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 * 
 */ 

#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 


int rpmvercmp(const char *, const char *); 


static inline int xislower(int c) { 
    return (c >= 'a' && c <= 'z'); 
} 

static inline int xisupper(int c) { 
    return (c >= 'A' && c <= 'Z'); 
} 

static inline int xisalpha(int c) { 
    return (xislower(c) || xisupper(c)); 
} 

static inline int xisdigit(int c) { 
    return (c >= '0' && c <= '9'); 
} 

static inline int xisalnum(int c) { 
    return (xisalpha(c) || xisdigit(c)); 
} 

static inline int xisblank(int c) { 
    return (c == ' ' || c == '\t'); 
} 

static inline int xisspace(int c) { 
    return (xisblank(c) || c == '\n' || c == '\r' || c == '\f' || c == '\v'); 
} 

static inline int xtolower(int c) { 
    return ((xisupper(c)) ? (c | ('a' - 'A')) : c); 
} 

static inline int xtoupper(int c) { 
    return ((xislower(c)) ? (c & ~('a' - 'A')) : c); 
} 

Teil 2c: Makefile

# $Id: Makefile,v 1.2 2003/03/06 17:54:19 luigi Exp $ 
# Makefile for rvc (RPM version compare) 

CC = gcc 
CFLAGS = -Wall 

all : rvc 

rvc : rvc.c  rvc.h 
   ${CC}  ${CFLAGS}  -o  $@  $< 

Installation:

Das C-Programm wird umgewandelt mit dem Aufruf make. Dadurch wird ein Programm rvc erstellt. Wer seinen apt-cache in einem anderen Verzeichnis stehen hat als /var/apt/cache sollte in dem Python-Script den Pfad anpassen. Beide Programmteile dann nach /usr/local/bin kopieren

cp rvc /usr/local/bin 
cp apt-smartclean.py /usr/local/bin 

Der Aufruf

apt-smartclean.py -s

zeigt an was obsolet im Cache rumsteht. Mit dem Aufruf

apt-smartclean.py

werden die obsoleten RPMs aus dem cache gelöscht.

Ich finde ein schönes Beispiel wie man zwei vorhandene Tools einfach kombiniert und schnell ein brauchbares Ergebnis erzielt.

Dieses Script hat für mich wunderbar funktioniert. Aber ich übernehme keine Haftung für die Anwendung und evtl Schäden an eurem System.

Hier noch eine Alternative:

1.) Download des Python-Scriptes von hier:

http://home.tiscali.cz:8080/~cz210552/distfiles/apt-smartclean.py

2.) diesen Patch als apt-smartclean-rpm.diff abspeichern:

--- apt-smartclean.py   2004-12-15 11:29:45.384724472 +0100 
+++ apt-smartclean-rpm.py       2004-12-15 11:30:28.928104872 +0100 
@@ -24,7 +24,7 @@ 
        packages={} # versions 
        fnames={}   # file names 
        for file in os.listdir(dir): 
-         if file[-4:] != '.deb': continue 
+         if file[-4:] != '.rpm': continue 
          parsed=file.split('_') 
          if len(parsed) != 3: continue 
          parsed[1]=parsed[1].replace('%3a',':') 
@@ -47,7 +47,7 @@ 

 if __name__=="__main__": 
     #working dpkg test 
-    sys.stdout.write("Running on Debian-") 
+    sys.stdout.write("Running on SuSE-") 
     sys.stdout.flush() 
     rc=os.spawnlp(os.P_WAIT,'dpkg','dpkg','--print-architecture') 
     if rc!=0: 

3.) mit patch -p0 < apt-smartclean-rpm.diff das Script patchen damit wird das portierte dpkg von debian für den Versionsvergleich genutzt.

4.) mit apt install deb das Paket deb installieren

5.) apt-smartclean.py installieren

cp apt-smartclean.py /usr/local/bin

ok, wenn cut & paste soooo schwierig ist ....

die RPMs liegen in meinem Repository suser-oc2pus.

apt install apt-smartclean 

die RPMs gibt es hier:

http://ftp.gwdg.de/pub/linux/suse/apt/SuSE/8.2-i386/RPMS.suser-oc2pus

http://ftp.gwdg.de/pub/linux/suse/apt/SuSE/9.1-i386/RPMS.suser-oc2pus

http://ftp.gwdg.de/pub/linux/suse/apt/SuSE/9.2-i386/RPMS.suser-oc2pus

http://ftp.gwdg.de/pub/linux/suse/apt/SuSE/9.3-i386/RPMS.suser-oc2pus

http://ftp.gwdg.de/pub/linux/suse/apt/SuSE/10.0-i386/RPMS.suser-oc2pus

http://ftp.gwdg.de/pub/linux/suse/apt/SuSE/10.1-i386/RPMS.suser-oc2pus


oc2pus


Zurück zur Quellcodes-Übersicht
Zurück zum Paketmanager