Entries filed under Perl

Using a Perl script because refactoring of a project with Android tools didn’t work

Posted on 20. Dezember 2014 Comments

I wanted to rename my project but I guess since it has a lot of dependencies that caused an error somewhere and I got the error message:

Refactoring
A fatal error occurred while performing the refactoring.
An unexpected exception occurred while creating a change object. See the error log for more details.

So I just the normal refactoring feature of Eclipse which not surprisingly also caused an error. After editing the AndroidManifest package entry, the import of the resources in the sources files didn’t work. It still said

import com.example.oldpackage.R

Only a couple of resource files needed manual editing but the Java files were a problem. What did the trick for me was this one-liner

perl -pi -w -e 's/import com.example.oldpackage.R/import com.example.newpackage.R/g;' `grep -r -l "import com.example.oldpackage.R"`

I realise this is rather quick&dirty (do a backup 😉 ) but it did work for this project. A short explanation:

perl

  • -pi puts the code in a loop (like -n, but sed-style)
  • -w gives you warnings
  • -e is one line of programm and since -pi
  • /g global, for all lines in the file

grep

  • -r recursive
  • -l give out files that matches the following search string

parallel-ssh mit perl

Posted on 9. August 2013 Comments

Es gibt ja das Programm parallel-ssh auf googlecode und auch in diversen Repositories, z.B. für Ubuntu. Ich habe allerdings dieses simple Perl Skript geschrieben um ein ähnliches Ergebnis zu erzielen. Da ich das über Webmin für ein bestimmtes Subnetz benutzen möchte, habe ich es konfigurierbar gehalten und das letzte Octect einer IP angegeben. Dabei ist mein Ziel hier gewesen, mich mit dem PublicKey-Verfahren anzumelden und eine bestimmte Datei oder einen Befehl auszuführen.

#!/bin/perl
$begin  = shift @ARGV;
$end    = shift @ARGV;

# if only one parameter given, only that IP will be used in the for-loop
if ($end == "") {
  $end = $begin;
}

# check if valid IPv4 address
if ($begin > $end || $begin > 255 || $end > 255 || $begin < 0 || $end < 0) {
  die "Die erste Zahl muss groesser als die zweite Zahl sein und muss eine Zahl zwischen 0 und 255 sein.\n ";
}

for (my $i = $begin; $i <= $end; $i++) {
  $bastelstring = "ssh user\@1.2.3." . $i . " befehl";
  $return = `$bastelstring`;
  print $return . "\n";
}

 

Alternativ kann man auch z.B. fest konfiguriert ein Array definieren:

 

@IPs = ("192.168.1.2", "192.168.1.3", "192.168.1.4");

foreach $IP(@IPs) {
  $bastelstring = "ssh user\@" . $IP . " befehl";
  $return = `$bastelstring`;
  print $return . "\n";
}

Bei Perl unter Windows 7 fehlt Tk und lässt sich nicht über cpan installieren

Posted on 7. Februar 2013 Comments

Die neue Perl Version enthält aus irgendeinem Grund Tk nicht (mehr?) standardmässig. Perl schlägt dann vor Tk mit dem folgendem Befehl nachzuinstallieren:

cpan -i Tk

Das funktioniert aber nicht, weil u.a. keine Compiler und Linuxtools wie make installiert sind. Also werden diese automatisch heruntergeladen. Allerdings schlägt die Installation trotzdem mit dem folgenden Ausgaben fehl:

rc -fo tk.res -r -i . -i mTk\win\rc mTk\win\rc\tk.rc
'rc' is not recognized as an internal or external command,
operable prgram or batch file.
dmake.exe: Error code 129, while making 'tk.res'
dmake.exe: Error code 255, while making 'pTk\libpTk.a'.

Was jedoch wunderbar und schnell funktioniert hat ist der folgende Befehl:

ppm install Tk

Pruefen ob ein Computer online ist mit ping und perl

Posted on 18. Mai 2012 Comments

Ich habe bei der Arbeit ein kleines Perl-Skript geschrieben, welches prüfen sollte, ob bestimmte Computer in bestimmten Räumen(also IP-Ranges) noch online sind oder schon automatisch ausgestellt wurden. Dieses Skript sendet ein Paket über ping und guckt dann, ob es ein packetloss gibt. Im Grunde wäre das in der Bash besser gewesen, aber so kann man das, wenn man es ein bisschen anpasst, auch unter anderen OS verwenden.

Code

# The string containsPacketLoss is searching for
$packetloss = "100% packet loss";
# Init
$returnval = "";

print "\nCheck if Computers are online...\n";

# Scan IP-Range
for (my $i = 1; $i <=255; $i++) {
	# c = one package, w = deadline, q = quiet
        $ipcmd = "ping -c1 -q -w1 169.254.1." . $i;
        # execute and retreive output
        $returnval = `$ipcmd`;
        if (containsPacketLoss() == 0) {
            # output
            print "Computer  with IP 169.254.1." . $i . "is still online.\n";
            # write log file
	    system("echo Computer with IP 169.254.1.". $i . localtime(time) . " ONLINE >> /home/user/log");
        }
}

sub containsPacketLoss(){
	# check by RegEx if the string specified above is in the returnvalue
	# of the ping command
	if ($returnval =~ m/$packetloss/ ){
                return 1;
        }
        return 0;
}

Download

Standarddrucker abhaengig vom Standort setzen

Posted on 24. Februar 2012 Comments

Auf der Arbeit sind die PCs fortlaufend beschriftet und die letzten 3 Zeichen ist der Raum, also z.B. PC22-123 ist der 22. PC in Raum 123. Die Räume sind dabei IMMER dreistellig, d.h. in Raum 42 wäre der Raum 042.

Mit einem kleinen Perlskript im Autostart bekommt man seinen gewünschten Drucker anhand des Hostnames:

use Sys::Hostname;
$host = hostname;
chomp($host);
$raumnr=substr($host,length($host)-3,length($host)-1);
print "Host: " . $host . "\n";
print "RaumNr: " . $raumnr . "\n";

if ($raumnr == 123) {
  system('rundll32 printui.dll,PrintUIEntry /y /n "Drucker_Raum_123"');
}
elsif (...)
else {
   print "Computername nicht im richtigen Format";
}

Den Hostname bekommt man vom System über sys::hostname. chomp() entfernt eventuelle newline characters. Mittels substr() bekommt man einen Teilstring zurück, der von der Länge-3 bis Länge -1 geht, also genau die letzten 3 Buchstaben bzw. Zahlen. Hier hat man dann die Raumnummer. Anhand derer wird mit der rundll ein Standarddrucker gesetzt(/y) der in Anführungszeichen hinter /n steht. Damit sich die Anführungszeichen nicht in die Quere kommen, nimmt man für den system() Befehl die einstelligen Hochkommata.

Cronjobs von selbst wieder anstellen

Posted on 11. Mai 2011 Comments

Das Problem war ganz einfach, manuell dürfen einige wenige Berechtigte aus guten Gründen Cronjobs abstellen. Damit aber am nächsten Tag der Cronjob wieder läuft braucht man ein (nicht-abstellbaren) Cron Jobs, der alle anderen Cronjobs wieder anstellt. Glücklicherweise gibt es da die Schnittstelle Config::Crontab und so sind dies nur ein paar Zeilen(via CPAN bzw. man Config::Crontab):

#!/usr/bin/perl
use Config::Crontab;
my $ct = new Config::Crontab;
$ct->read; # alle crons auslesen a.k.a. crontab -l
$_->active(1) for $ct->select(-command_re => '/usr/local/bin/command'); # zeile vervielfachen fuer andere befehle
$ct->write; # alle crontabs schreiben, nicht vergessen!

Der gewünschte, nun wieder aktive Befehl ist /usr/local/bin/command.