Dies ist ein Template für den Skripte-Unterbereich
InhaltPerlSkripteDebug.
Wie finde ich alle installierten Module?
Name
FindAllModules?
Aufgabe
Finden und Augeben von allen Installierten Modulen sowie die Ausgabe der Version.
Funktionsweise
Finden aller erreichbaren Module und bestimmen ihrer Version.
Das Script hat zwei Möglichkeiten Module zu finden und zu listen.
- In der ersten Variante wird das Modul ExtUtils?::Installed verwendet, um Module zu finden.
- Die zweite Varianten arbeitet gänzlich ohne Module unddurchsucht die Pfade in "@INC" und sucht alle Modulle (Dateien, die auf "pm" enden)
Weiterhin gibt es zwei Optionen um die Modulversion zu bestimmen.
- Die erste Version list die Modue aus und sucht darin nach einer Zeile die "$VERSION" enthält und Interpertiert diese. Hierbei Kann es sein, dass die Angabe nicht korrekt ist, jedoch funktioniert das möglicherweise auch bei Modulen, die nicht mehr ladbar sind.
- In der Zweitern Version wird Das Modul geladen und die Version ausgelesen. Die Angabe ist exakter, jedoch kann es zu großem Speicherverbruach und Prozessorlast kommen. Zudem ist die Varianten signifikant langsamer.
Das Script kann sowohl von der Konsole aus aufgerufen werden als auch aus dem CGI-Verzeichnis eines Webspace. Es versucht austomatisch zu erkennen In welchem Kontext der Aufruf erfolgt.
Aufruf mit Parametern
der Aufruf über die Konsole ist wie folgt:
scriptname [vsimple] [vuse] [extutils] [rsimple] [rslong][pversion][pvlong]
Der Aufruf übers Web ist wie folgt:
http://server/cgi-bin/scriptname?[vsimple[&]][vuse[&]][extutils[&]][rsimple[&]][rslong[&]][pversion[&]][pvlong[&]]
Ohne Angaben wird das sich Scipt aktionslos beenden.
vsimple -- das Script versucht die Version eines Modules zu ermitteln,
Indem es das Modul als datei öffnet
und die Zeile mit "$VERSION =" zu interpretieren versucht.
vuse -- das Script versucht die Version des Scriptes zu ermittel,
Indem es versucht die gefundenen Module zu laden
und mittels "$Modul::VERSION" die Version zu ermitteln.
Das kann Lange dauern und ist Speicher- und Prozessorlastig.
extutils -- es wird das Modul ExtUtils::Installed verwendet,
um alle installierten Module zu ermitteln.
rsimple -- Ohne ein Modul zu verwenden werden alle bekannten Perlmodulordner durchsucht,
und die darin gefundenen Module gelistet.
Dabei werden sehr viel mehr Module gefunden als mit der option "extutils".
Zum einen werden auch alle Core-Module gefunden
(Module, die zur Basisinstallation gehören),
als auch Module, die zu einem gößeren Bundle gehören
und eigenständig nicht verwendbar währen.
Es wird schon versucht die Liste zu verkürzen,
indem Module mur Module gelistet werden,
die scheinbar untergordnetet Module haben.
(*.pm und Verzeichnis selben Namens)
Dabei werden unter Umständen zu viele Module verworfen
rslong -- Wie "rsimple", es wird aber darauf verzichtet,
die Liste der Module zu verkürzen.
pversion -- Gibt die perl Version aus
pvlong -- Gibt die perl Version aus wie sie von "perl --version" produziert wird
Skript
#!/usr/bin/perl
#use strict;
#use warnings;
# Dieses Script versucht alle installierten Module zu finden
# und deren Version aus zu geben.
# Man kann es von der Konsole starten,
# oder aus dem cgi-bin Verzeichnis seines Webspace
# Da es fast keine Module verwendet sollte es auch auf vielen unvollständigen
# oder defekten Perlinstallationen lauffähig sein.
# (aber ich übernehme keinerlei Gewähr)
#
# Das Script akzeptiert folgende Kommandos:
# vsimple -- das Script versucht die Version eines Modules zu ermitteln,
# Indem es das Modul als datei öffnet
# und die Zeile mit "$VERSION =" zu interpretieren versucht.
#
# vuse -- das Script versucht die Version des Scriptes zu ermittel,
# Indem es versucht die gefundenen Module zu laden
# und mittels "$Modul::VERSION" die Version zu ermitteln.
# Das kann Lange dauern und ist Speicher- und Prozessorlastig.
#
# extutils -- es wird das Modul ExtUtils::Installed verwendet,
# um alle installierten Module zu ermitteln.
#
# rsimple -- Ohne ein Modul zu verwenden werden alle bekannten Perlmodulordner durchsucht,
# und die darin gefundenen Module gelistet.
# Dabei werden sehr viel mehr Module gefunden als mit der option "extutils".
# Zum einen werden auch alle Core-Module gefunden
# (Module, die zur Basisinstallation gehören),
# als auch Module, die zu einem gößeren Bundle gehören
# und eigenständig nicht verwendbar währen.
# Es wird schon versucht die Liste zu verkürzen,
# indem Module mur Module gelistet werden,
# die scheinbar untergordnetet Module haben.
# (*.pm und Verzeichnis selben Namens)
# Dabei werden unter Umständen zu viele Module verworfen
#
# rslong -- Wie "rsimple", es wird aber darauf verzichtet,
# die Liste der Module zu verkürzen.
#
# pversion -- Gibt die perl Version aus
#
# pvlong -- Gibt die perl Version aus wie sie von "perl --version" produziert wird
#
#
# das script macht nichts solange keine Option angeben wurde
# Da es auch im Web laufen soll habe ich aus Sicherheitsgründen auf eine Hilfe verzichtet.
# Veraltete Module können ein Einfallstoor für Cracker sein,
# die sich darüber das Servers bemächtigen könnten.
#
# der Aufruf über die Konsole ist wie folgt:
# scriptname [vsimple] [vuse] [extutils] [rsimple] [rslong]
# wobei die Reihenfolge unwesentlich ist.
#
# der Aufruf übers Web ist wie folgt:
# http://server/cgi-bin/scriptname?[vsimple&][vuse&][extutils&][rsimple&][rslong&]
# auch hier ist die reihenfolge unwichtig.
########################################################################
sub get_version_simple($)
{
my $file=shift;
my $version='';
if(open(my $fh, '<', $file))
{
while(my $line=<$fh>)
{
if($line=~/\$VERSION\s*=(.+?)$/)
{
no warnings;
$version= eval 'return '.$1;
$version+=0;
last;
}
}
close($fh);
}
return $version;
}
sub get_version_use($)
{
my $module=shift;
#no warnings;
my $version= eval('
no warnings;
no strict;
require '.$module.';
return $'.$module.'::VERSION;
');
warn "TEST\n";
$version=0 unless($version);
return $version;
}
sub test_version_and_print($$)
{
my $list=shift;
my $version=shift;
for my $modul (@$list)
{
my $v=0;
if($version==1)
{
(my $path=$modul)=~s!::!/!g;
for my $base (@INC)
{
if(-f "$base/$path.pm")
{
$v=get_version_simple("$base/$path.pm");
unless($v)
{
if(-f "$base/$path/VERSION.pm")
{ $v=get_version_simple("$base/$path/VERSION.pm"); }
elsif(-f "$base/$path/Version.pm")
{ $v=get_version_simple("$base/$path/Version.pm"); }
}
last;
}
}
}
elsif($version==2)
{
# keine Fehlermeldungen...
close(STDERR);
$v=get_version_use($modul);
}
print $modul.($v?" ($v)":'')."\n";
}
}
########################################################################
sub extutils
{
use ExtUtils::Installed;
test_version_and_print([sort ExtUtils::Installed->new()->modules()],shift);
}
########################################################################
sub read_dir_recursive($$$$)
{
my $modules=shift;
my $old=shift;
my $module=shift;
my $dir=shift;
return if(grep{$dir eq $_}@$old);
push(@$old,$dir);
if(opendir(my $dh, $dir))
{
my @entrys=readdir($dh);
closedir($dh);
for my $entry (@entrys)
{
next if(index($entry,'.') == 0);
if(-f "$dir/$entry" && $entry=~/^(.+)\.pm$/)
{ $modules->{join('::', @$module,$1)}++; }
elsif(-d "$dir/$entry")
{ read_dir_recursive($modules,$old,[@$module,$entry],"$dir/$entry"); }
}
}
}
sub read_simple($$)
{
my $version=shift;
my $long=shift;
my %modules=();
my @old=();
for my $path (sort{length($b) <=> length($a)} @INC)
{
#print "$path\n";
read_dir_recursive(\%modules,\@old,[],$path);
push(@old,$path);
}
my @list;
if($long)
{
for my $module (sort keys(%modules))
{
if(index($module,'::')>0)
{
(my $path=$module)=~s!::!/!g;
for my $base (@INC)
{
if(-f "$base/$path.pm" && -d "$base/$path")
{
push(@list,$module);
last;
}
}
}
else
{ push(@list,$module); }
}
}
else
{ @list=sort keys(%modules); }
test_version_and_print(\@list,$version);
}
sub perl_version($)
{
my $type=shift || 0;
if($type==0)
{ print "Perl Version: $]\n"; }
else
{ print `perl --version`; }
}
########################################################################
########################################################################
########################################################################
print "Content-Type: text/plain\r\n\r\n" if($ENV{REMOTE_ADDR});
my $cmd=$ENV{QUERY_STRING};
unless($cmd)
{ $cmd=@ARGV?join(' ',@ARGV):""; }
my $version=0;
if($cmd=~/vsimple/)
{ $version=1; }
elsif ($cmd=~/vuse/)
{ $version=2; }
print "#"x80,"\n";
if($cmd=~/pversion/)
{ perl_version(0); }
elsif($cmd=~/pvlong/)
{ perl_version(1); }
print "#"x80,"\n";
if($cmd=~/rslong/)
{ read_simple($version,1); }
elsif ($cmd=~/rsimple/)
{ read_simple($version,0); }
print "#"x80,"\n";
extutils($version) if($cmd=~/extutils/);
print "#"x80,"\n";
Ergänzungen, Kommentare
Kommentare werden am besten in folgender Form vorgenommen, damit sie im Inhaltsverzeichnis angezeigt werden (natürlich ohne das <verbatim>):
---### Main.??? - 14 Jul 2003 - Betreff