Apt cache aufraeumen: Unterschied zwischen den Versionen
K (Kategorie angepasst da nun die Kategorie Paketmanager mit Unterkategorien existiert) |
K (Kategorie angepasst da nun die Kategorie Paketmanager mit Unterkategorien existiert) |
||
Zeile 411: | Zeile 411: | ||
---- | ---- | ||
− | [[ | + | [[Shellcripte|Zurück zur Shellscripte Übersicht]]<br /> |
[[APT|Zurück zur Apt und Smart Übersicht]]<br/> | [[APT|Zurück zur Apt und Smart Übersicht]]<br/> | ||
[[Category:APT]] | [[Category:APT]] | ||
[[Category:Scripte]] | [[Category:Scripte]] |
Version vom 30. Januar 2007, 15:31 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 Shellscripte Übersicht
Zurück zur Apt und Smart Übersicht