Showing posts with label perl. Show all posts
Showing posts with label perl. Show all posts

Tuesday, July 12, 2011

perl to translate chars

$a =~ tr/[A-Z]/[a-z]/; 

Try it with
perl -e '$a = "ABCD"; $a =~ tr/[A-Z]/[a-z]/; print $n;'$a;

Tuesday, March 1, 2011

Catch 22 using exec in perl forks

I just found a nasty little problem using perl exec.

#!/usr/bin/env perl

my @a = ("sh -c 'asdfsadf ls'", "echo hi", "echo a");

foreach my $b (@a) 
{
    if(fork()==0) 
    {
        exec($b); 
        die "Gahh: $b";
    }
}

print "done\n";

Note what happens when in the case of sub shells and exec:
perl -e "exec('sh -c asdflkj'); die 'gahh';"

Thursday, February 17, 2011

Perl generic data structure dumper

Here is a quick function to dump the contents of a generic mass of variables. I use it to debug the mass of random data structures that appear in random perl scripts

sub rec_print
{
    my ($message, $lead) = @_;
    
    if (ref($message) eq 'ARRAY') 
    { 
       # print  ":\n";        
        rec_print($_, $lead . " ")  foreach (@$message);
    }
    elsif (ref($message) eq 'HASH') 
    {
        foreach my $k (keys %$message)
        {
            print  "$lead$k:\n";
            rec_print($message->{$k}, $lead . " ");
        }
    }
    else
    {
        print "$lead$message\n";
    }
}

#example
rec_print({a=>"abc", b=>"bcd"},"");

Friday, October 29, 2010

Perl World clock

Heres another hacked up script that gives the time locally on the system(mine is NYT), the time in japan and the number of seconds fro NYT midnight..

Try running it(called datetime.pl) with these commands lines:
./datetime.pl 
./datetime.pl "7:00"
./datetime.pl "+ 1 day + 1 hours"
./datetime.pl "-10 seconds"

#!/usr/bin/env perl

use strict;
use Date::Manip;

sub string2date
{
    my ($str) = @_;
    return int(UnixDate($str, "%s")); 
}

sub date2string
{
    my ($time) = @_;
    return UnixDate("epoch $time", "%m/%d/%y %H:%M:%S"); 
}

sub date2timezone
{
    my ($time, $tz) = @_;

    return UnixDate(Date_ConvTZ(ParseDate("epoch $time"), '', $tz), '%m/%d/%y %H:%M:%S');
}

sub date2midnightSec
{
    my ($time) = @_;
    my @a = localtime($time); 
    return 3600*@a[2] + 60*@a[1] + @a[0];
}

my $intime = $ARGV[0];
$intime = 'now' unless defined $intime;

my $rawInTime  = string2date($intime);
print "NYT: " . date2string($rawInTime) . "\n";
print "JST: " .  date2timezone($rawInTime, "JST") . "\n";
print "Midnight Seconds: " .  date2midnightSec($rawInTime) . "\n";

hacky crontab replacement in perl

I love system admins. I have been one my self. All that power at the tips of my fingers, and a manager with a big club behind me, waiting to play wack a mole with my fingers if i mees up. Of course system admins can tell a coder that he doesn't have access to cron.... but guess what: cron was written by programmers soo.... hack yourself up a 30 min crontab system in perl and chuckle in your sleep.

Heres my hacked up mess for the day.

#!/usr/bin/env perl

use strict;
use Date::Manip;

#For the valid formats look at 
#http://search.cpan.org/~muir/Time-modules-2003.0211/lib/Time/ParseDate.pm

my $period = 10;
my @tasks = (
             { time => "09:00:00", label => "morning", cmd  => "echo 'good morning'"},
             { time => "01:34:00", label => "Hi", cmd  => "echo 'good morning'"},
             { step => "+ 1 minutes", label => "5 mins", cmd  => "echo '5 mins'"},
             { step => "+ 10 seconds", label => "10 seconsd", cmd  => "echo '5 mins'"}
             
             );

sub string2date
{
    my ($str) = @_;
    return int(UnixDate($str, "%s")); 
}

sub secsDiff
{
    my ($str) = @_;
    return string2date($str) - string2date("now");
}

sub update_firetime
{
    my ($task, $now) = @_;
    my $new = $now;
    if(defined $task->{time})
    {
        $new = string2date($task->{time});
        $new += secsDiff("+ 1 day") if $new < $now;
    }
    elsif(defined $task->{step})
    {
        $new  = $now;
        $new += secsDiff($task->{step}) while $new <= $now;
    }
    $task->{fire_time} = $new;

}

sub boot
{
    my $now = string2date("now");    
    update_firetime($_, $now)
        foreach (@tasks);
}

sub execute
{
    my ($task) = @_;

    my $pid = fork();
    if((defined $pid) && ($pid == 0)) 
    {
        if(defined $task->{xterm} && $task->{xterm} == 1)
        {
            #boot and leave an xt
            my $label   = $task->{label};
            my $cmd     = $task->{cmd};
            my $sys_cmd = "xterm -xrm 'XTerm*foreground: red3' -xrm 'XTerm*background: black' -title 'CRONTAB:$label' -e sh -c \"$cmd; ksh\" &";
            
            system($sys_cmd);
        }
        else
        {
            #just execute it..
            system($task->{cmd});
        }
        exit(0);
    }
}

sub cron_core
{
    while(1)
    {
        my $now = string2date("now");
        foreach my $task (@tasks)
        {
            if($now > $task->{fire_time})
            {
                print "fire! $task->{label}\n";
                execute($task);
                update_firetime($task, $now) 
            }
        }
        #cron loop an launch
        
        print("sleeping.....\n");
        sleep($period);
    }
}

print "Operating with an accuracy of +/-$period seconds\n";

boot();
cron_core();

Wednesday, September 29, 2010

A perl implementation of find

Recently working on a system which has a busted find command need a fix.. it is about 300% slower than the real thing so use it when needed only

#!/usr/bin/env perl

use strict;
use warnings;
use Cwd;

my $start=$ARGV[0];

sub find
{
    my ($dirname) = @_;
    my $dh;
    opendir($dh, $dirname) or die "Couldn't open dir '$dirname': $!";
    my @files = readdir($dh);
    closedir($dh);

    #print files...
    foreach my $file (@files) 
    {
 if(
    ($file) &&
    ($file !~ /^\.$/) &&
    ($file !~ /^\.\.$/)
    )
 {
     my $path = "$dirname/$file";
     print "$path\n";
     if(-d "$path")
     { 
  find("$path"); 
     }
 }
    }
}

$start = "." unless $start;

find($start);