Perl-Skripte reproduzierbar umziehen
Schicker Umzug
Wer viel in der Shell arbeitet und navigiert, nach Textstücken sucht oder CPAN-Module installiert, wird die hier vorgestellten Helferskripte bestimmt schnell schätzen lernen.
© zettberlin, photocase.com
Wer viel in der Shell arbeitet und navigiert, nach Textstücken sucht oder CPAN-Module installiert, wird die hier vorgestellten Helferskripte bestimmt schnell schätzen lernen.
Neulich zog ich auf einen neuen Entwicklungs-Desktop um und packte die Gelegenheit beim Schopf, mein überquellendes Homeverzeichnis nicht nur aufzuräumen, sondern neu aufzubauen. Dort hatten sich über die Jahre Hunderte von teilweise schon wieder obsoleten Helferskripten angesammelt. Um Ordnung in das Chaos zu bringen, beschloss ich, wirklich bei null anzufangen und die erst bei der täglichen Tipparbeit tatsächlich vermissten Skripte nachzuinstallieren – in reproduzierbarer Art und Weise, versteht sich, auf dass der nächste Umzug wie von allein vonstattengehe.
Alle Skripte sollen danach in Unterverzeichnissen verschiedener Git-Repositories liegen. Damit der Benutzer die Helferlein ohne Pfadangabe aufrufen kann, zeigen Symlinks vom »bin«
-Pfad des Homeverzeichnisses zu den eigentlichen Skripten. Ein weiteres Skript, »binlinks«
, ordnet in seinem »DATA«
-Bereich den ins Git-Repository eingecheckten Skripten Links im lokalen »bin«
-Verzeichnis des Users zu. So verbleibt zum Beispiel das Skript »logtemp«
zum Auslesen des in [2] vorgestellten Temperaturfühlers im Git-Repository »articles«
, während das handgeschriebene Konvertierwerkzeug »cvs2git«
im Schilli-Labs-Repository »sandbox«
aufgehoben ist.
Kommt ein neues Skript in den »bin«
-Bereich hinzu, trägt der Entwickler es ans Ende des »DATA«
-Bereichs von »binlinks«
ein und ruft Letzteres auf (Listing 1). Es klappert dann alle Einträge ab, verifiziert, ob der gewünschte Link in »~/bin«
schon existiert, und legt ihn nötigenfalls an. Dass »binlinks«
selbst wiederum in einem Git-Repository liegt, sollte klar sein. Es nutzt das Modul Sysadm::Install vom CPAN – einzig wegen dessen Funktion »mkd()«
, die neue Verzeichnisse ohne Murren anlegt und mit Log4perl-Ausgaben zum Ablauf Auskunft gibt.
Listing 1
binlinks
01 #!/usr/local/bin/perl -w
02 use strict;
03 use Log::Log4perl qw(:easy);
04 use File::Basename;
05 use Sysadm::Install qw(mkd);
06
07 Log::Log4perl->easy_init($DEBUG);
08
09 my ($home) = glob "~";
10 my $home_bin = "$home/bin";
11
12 while (<DATA>) {
13 chomp;
14
15 my ($linkbase, $src) = split ' ', $_;
16
17 $src = "$home/$src";
18 my $binpath = "$home_bin/$linkbase";
19
20 if (-l $binpath) {
21 DEBUG "$binpath already exists";
22 next;
23 } elsif (-e $binpath) {
24 ERROR "$binpath already exists, ",
25 "but not a link!";
26 next;
27 }
28
29 INFO "Linking $binpath -> $src";
30
31 symlink $src, $binpath
32 or LOGDIE
33 "Cannot link $binpath->$src ($!)";
34 }
35
36 __DATA__
37 logtemp git/articles/temper/eg/logtemp
38 cvs2git git/sandbox/cvs2git/cvs2git
So handelt es sich bei einem aufgerufenen Skript häufig um einen Symlink. Wenn ein Symlink zu einer Datei in einem anderen Verzeichnis zeigt, möchten Entwickler gerne mit »cd«
dorthin wechseln. Dies erledigt das Kommando »lcd«
mit dem Link als Parameter (Abbildung 1).
Alte Unix-Hasen wissen natürlich, dass ein Skript nicht das aktuelle Verzeichnis des Aufrufers wechseln kann. Skripte laufen in einer Subshell ab, und bei deren Beendigung sind für den Aufrufer keine nachhaltigen Nebenwirkungen bemerkbar. Aus diesem Grund ist »lcd«
im Startskript ».bashrc«
der Shell als Bash-Funktion definiert:
function lcd () { cd `symlinkdir $1`; \
pwd; ls; }
Ruft der Anwender nun »lcd bin/cvs2git«
auf, dann übergibt die Bash-Funktion das Argument »bin/cvs2git«
an das Skript »symlinkdir«
und ruft das Shellkommando »cd«
mit dessen Ausgabe auf. Die Implementierung von »symlinkdir«
ist in Listing 2 zu sehen.
Listing 2
symlinkdir
01 #!/usr/local/bin/perl -w
02 use strict;
03 use File::Basename;
04
05 my($link) = @ARGV;
06
07 die "No link specified" unless $link;
08 die "$link not a symbolic link"
09 unless -l $link;
10
11 while(-l $link) {
12 $link = readlink($link);
13 }
14
15 $link = dirname($link) unless -d $link;
16 print "$link\n";
Das Skript folgt mit der Systemfunktion »readlink()«
dem als Parameter überreichten Link und wiederholt dies so lange, bis das Ergebnis kein Link mehr ist. Die Funktion »dirname()«
aus dem Modul File::Basename extrahiert aus dem resultierenden Pfad das Verzeichnis und Zeile 16 gibt es auf der Standardausgabe aus, wo die Bash-Funktion »lcd()«
es aufschnappt, dorthin wechselt, es mit »pwd«
ausgibt und mit »ls«
die dort liegenden Einträge auflistet.
Umfang: 3 Heftseiten
Preis € 0,99
(inkl. 19% MwSt.)
Alle Rezensionen aus dem Linux-Magazin
Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...