<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Altentee &#187; Performance &#38; Test Automation Experts &#187; perl</title>
	<atom:link href="http://altentee.com/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://altentee.com</link>
	<description>Performance and Test Automation Experts</description>
	<lastBuildDate>Sat, 12 Jun 2010 00:35:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Leopard Perl 5.8.8 installation throws errors when compiling (makefile)</title>
		<link>http://altentee.com/2007/leopard-perl-588-installation-throws-errors-when-compiling-makefile/</link>
		<comments>http://altentee.com/2007/leopard-perl-588-installation-throws-errors-when-compiling-makefile/#comments</comments>
		<pubDate>Thu, 06 Dec 2007 04:05:43 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2007/leopard-perl-588-installation-throws-errors-when-compiling-makefile/</guid>
		<description><![CDATA[<p>If you&#8217;re stuck with this error when trying to compile your own apps:</p>
<p>No rule to make target `/System/Library/Perl/5.8.8/darwin-thread-multi-2level/CORE/config.h', needed by `Makefile'.</p>
<p>You will probably find that your Leopard installation is lacking some necessary files.
If you copy the files from your old(er) installation of perl (5.8.6) you should be able to get around this &#8230;</p>
<p>sudo cp /System/Library/Perl/5.8.6/darwin-thread-multi-2level/CORE/* [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re stuck with this error when trying to compile your own apps:</p>
<p><code>No rule to make target `/System/Library/Perl/5.8.8/darwin-thread-multi-2level/CORE/config.h', needed by `Makefile'.</code></p>
<p>You will probably find that your Leopard installation is lacking some necessary files.<br />
If you copy the files from your old(er) installation of perl (5.8.6) you should be able to get around this &#8230;</p>
<p><code>sudo cp /System/Library/Perl/5.8.6/darwin-thread-multi-2level/CORE/* /System/Library/Perl/5.8.8/darwin-thread-multi-2level/CORE/</code></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2007/leopard-perl-588-installation-throws-errors-when-compiling-makefile/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Automating your scripts with WWW::Mechanize</title>
		<link>http://altentee.com/2007/automating-your-scripts-with-wwwmechanize/</link>
		<comments>http://altentee.com/2007/automating-your-scripts-with-wwwmechanize/#comments</comments>
		<pubDate>Mon, 24 Sep 2007 01:32:00 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[Altentee]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2007/automating-your-scripts-with-wwwmechanize/</guid>
		<description><![CDATA[<p>CPAN provides a great module for Perl called WWW:Mechanize. To quote CPAN:
WWW::Mechanize, or Mech for short, helps you automate interaction with a website. It supports performing a sequence of page fetches including following links and submitting forms. Each fetched page is parsed and its links and forms are extracted. A link or a form can [...]]]></description>
			<content:encoded><![CDATA[<p>CPAN provides a great module for Perl called WWW:Mechanize. To quote CPAN:<br />
<blockquote>WWW::Mechanize, or Mech for short, helps you automate interaction with a website. It supports performing a sequence of page fetches including following links and submitting forms. Each fetched page is parsed and its links and forms are extracted. A link or a form can be selected, form fields can be filled and the next page can be fetched. Mech also stores a history of the URLs you&#8217;ve visited, which can be queried and revisited.</p></blockquote>
<p>This post details how to install the module as well as a quick example of automation that logs in to a secure website (MyThree.com.au) and extracts information (Bill Info &#038; Data Usage) without ever having to leave your console &#8230;</p>
<p><span id="more-288"></span><br />
<strong>Installation</strong><br />
I like to use the ActiveState package of Perl, which comes pre-installed with LWP (if on Windows). If however you are installing on a non-windows platform, you may need to update your Perl installation with the LWP module. I think the easiest way to do this is to download the module direct from CPAN <a href="http://search.cpan.org/search?dist=libwww-perl">here</a>. If you don&#8217;t do this, then your cpan console will most likely return the following type of error whenever you try to install a new module:<br />
<code>   cpan> Could not fetch authors/
<packagename>.gz<br />
   LWP not available </code></p>
<p>Once downloaded you can install libwww-perl using the normal Perl module distribution drill:<br />
<code>   sudo perl Makefile.PL<br />
   sudo make<br />
   sudo make test<br />
   sudo make install</code></p>
<p>Now you can use the CPAN console to update modules in your perl installation easily.<br />
If you are using a win32 platform, I wouldn&#8217;t bother with the cpan console, I would just use the Perl Package Manager and install the win32 bundles direct from the following repository:<br />
<code>   ppm install http://theoryx5.uwinnipeg.ca/ppms/WWW-Mechanize.ppd<br />
   ppm install http://theoryx5.uwinnipeg.ca/ppms/Crypt-SSLeay.ppd</code></p>
<p>However if you&#8217;re on a *nix environment, then the cpan console is perhaps your best bet:<br />
<code>   >sudo cpan<br />
   install Bundle::CPAN #this isn't mandatory, but it's good to update in general<br />
   install IO::Socket::SSL<br />
   install HTML::TokeParser<br />
   install WWW::Mechanize<br />
   install Crypt::SSLeay #if you're going to automate https transactions<br />
</code></p>
<p><strong>Example Code</strong><br />
Now that you&#8217;ve installed the module, you can write some code that will automate actions performed on a typical web site that uses https communications. In the following example, I automate a user logging in to a secure website (www.my.three.com.au) who then obtains summary billing and usage information.</p>
<p>Make sure you include the use statements required to add this module&#8217;s functionality to your code:<br />
<code>   use WWW::Mechanize;<br />
   use Crypt::SSLeay;</code></p>
<p>Create a new mech object:<br />
<code>   $mech        = WWW::Mechanize->new();<br />
</code></p>
<p>Open a URL and check the http return code:<br />
<code>   $url = 'https://www.my.three.com.au/My3/jfn';<br />
   $result = $mech->get( $url );<br />
   die "GET failed\n" unless $result->is_success;</code></p>
<p>Submit a form on the web page after providing some html field details and check the http return code:<br />
<code>   $result = $mech->submit_form(<br />
		form_name 	=> 'login',<br />
		fields 		=> {<br />
		login       => $mobile,<br />
		password	=> $password<br />
		}<br />
   );<br />
   die "SUBMIT failed\n" unless $result->is_success;</code></p>
<p>Parse the string that is returned from a successful login for relevant information:<br />
<code>   $content = $result->as_string();<br />
   if($content =~ /\<b\>\$ ([0-9\.]+)/)<br />
   {<br />
	$value = $1;<br />
	print "Total Balance Due \t\t\$$value \n";<br />
   }</code></p>
<p>Simulate clicking on an embedded link within a frame. To figure out the URL query parameters, and sub frame page information I like to use Firefox&#8217;s page info feature to determine the correct parameters and sequence. Another handy plugin is LiveHTTP headers, which lets you scrutinize transactions, capture them, replay them and so on.<br />
<a href='http://90kts.com/blog/wp-content/uploads/2007/09/picture-2.png' title='picture-2.png'><img src='http://90kts.com/blog/wp-content/uploads/2007/09/picture-2.thumbnail.png' alt='picture-2.png' /></a><br />
<code>   $params="selectedLineNumber=$mobile&#038;&#038;oid=L7%3A3714843&#038;ctx=L&#038;mfunc=1055&#038;jfnRC=7";<br />
   $url="https://www.my.three.com.au/My3/jfn?$params";<br />
   $result = $mech->get( $url	);<br />
   die "GET failed\n" unless $result->is_success;</code></p>
<p>Parse for further content such as your data usage summary:<br />
<code>   $content = $result->as_string();<br />
   if($content =~ /Mobile Broadband \(2048.*\n.*\n.*\n\s+(\d+\.\d+)/)<br />
   {<br />
	$value = $1;<br />
	print "Mobile Broadband Remaining \t$value GB \n";<br />
   }</code></p>
<p><strong>Execution</strong><br />
Test and execute your code. The example code below prints billing and usage operation from the console. You can then automate this functionality into other aspects of your operating system (on Mac OSX I like to make widgets that achieve similar outcomes):<br />
<code>   /Users/Koops/Documents/working/90KTS>./MyThree.pl<br />
   Opened login page ...<br />
   Passed 1st login  ...<br />
   Passed 2nd login  ...<br />
   Total Balance Due               $49.00<br />
   Mobile Broadband Remaining      1108.083 MB </code></p>
<p><strong>Complete Code Example</strong><br />
<code>#!/usr/bin/perl<br />
# $Id: MyThree.pl,v 1.0 2007/09/24 03:29:19 Koops Exp $<br />
use WWW::Mechanize;<br />
use Crypt::SSLeay;</p>
<p>$mech        = WWW::Mechanize->new();<br />
my $mobile   = "041123456";<br />
my $password = "password";<br />
my $pin      = "pinNumber";</p>
<p>$url = 'https://www.my.three.com.au/My3/jfn';<br />
$result = $mech->get( $url );<br />
die "GET failed\n" unless $result->is_success;<br />
print "Opened login page ...\n";</p>
<p>$result = $mech->submit_form(<br />
		form_name 	=> 'login',<br />
		fields 		=> {<br />
		login       => $mobile,<br />
		password	=> $password<br />
		}<br />
);<br />
die "SUBMIT failed\n" unless $result->is_success;<br />
print "Passed 1st login  ...\n";</p>
<p>$result = $mech->submit_form(<br />
		form_name 	=> 'myForm',<br />
		fields 		=> {<br />
		pin	        => $pin<br />
		}<br />
);<br />
die "SUBMIT failed\n" unless $result->is_success;<br />
print "Passed 2nd login  ...\n";</p>
<p>$content = $result->as_string();<br />
if($content =~ /\<b\>\$ ([0-9\.]+)/)<br />
{<br />
	$value = $1;<br />
	print "Total Balance Due \t\t\$$value \n";<br />
}</p>
<p>$params="selectedLineNumber=$mobile&#038;contractType=POSTPAID&#038;&#038;oid=L7%3A3714843&#038;ctx=L&#038;mfunc=1053&#038;jfnRC=2";<br />
$url="https://www.my.three.com.au/My3/jfn?$params";<br />
$result = $mech->get( $url	);<br />
die "GET failed\n" unless $result->is_success;</p>
<p>$params="selectedLineNumber=$mobile&#038;&#038;oid=L7%3A3714843&#038;ctx=L&#038;mfunc=1055&#038;jfnRC=7";<br />
$url="https://www.my.three.com.au/My3/jfn?$params";<br />
$result = $mech->get( $url	);<br />
die "GET failed\n" unless $result->is_success;</p>
<p>$content = $result->as_string();<br />
if($content =~ /Mobile Broadband \(2048.*\n.*\n.*\n\s+(\d+\.\d+)/)<br />
{<br />
	$value = $1;<br />
	print "Mobile Broadband Remaining \t$value MB \n";<br />
}</code></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2007/automating-your-scripts-with-wwwmechanize/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using perl to get, put and delete on Amazon S3 storage</title>
		<link>http://altentee.com/2007/using-perl-to-get-put-and-delete-on-amazon-s3-storage/</link>
		<comments>http://altentee.com/2007/using-perl-to-get-put-and-delete-on-amazon-s3-storage/#comments</comments>
		<pubDate>Mon, 06 Aug 2007 06:36:15 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[Altentee]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2007/using-perl-to-get-put-and-delete-on-amazon-s3-storage/</guid>
		<description><![CDATA[<p>Amazon web services development domain have provided some neat perl code here such that you can simply put, get or delete objects inside an Amazon S3 storage bucket with something like this:</p>
<p>./s3curl.pl --id=[aws-access-key-id] --key=[aws-secret-access-key] -- http://s3.amazonaws.com/[bucket-name]/[key-name] </p>
<p>I modified the author&#8217;s code to make it a bit more win32 friendly, as it is no surprise that [...]]]></description>
			<content:encoded><![CDATA[<p>Amazon web services development domain have provided some neat perl code <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=128">here</a> such that you can simply put, get or delete objects inside an Amazon S3 storage bucket with something like this:</p>
<p><code>./s3curl.pl --id=[aws-access-key-id] --key=[aws-secret-access-key] -- http://s3.amazonaws.com/[bucket-name]/[key-name] </code></p>
<p>I modified the author&#8217;s code to make it a bit more win32 friendly, as it is no surprise that DPHOTO uses perl and a win32 platform to launch its tertiary backups.</p>
<p><span id="more-284"></span><br />
What I needed to do was convert the code provided by the author into a couple of succinct win32 friendly functions, to use within your own perl code.</p>
<p>The first part needed a function that could sign your host ID with an appropriate hash. You can use the following function to achieve this.<br />
<code><br />
sub getResourceToSign<br />
	{<br />
    	my ($host, $resourceToSignRef) = @_;<br />
	    for my $ep (@endpoints) {<br />
	        if ($host =~ /(\w+).$ep/) { # vanity subdomain case<br />
	            my $vanityBucket = $1;<br />
	            $$resourceToSignRef = "/$vanityBucket".$$resourceToSignRef;<br />
	            return;<br />
	        }<br />
	        elsif ($host eq $ep) {<br />
	            return;<br />
	        }<br />
	    }<br />
	    # cname case<br />
	    $$resourceToSignRef = "/$host".$$resourceToSignRef;<br />
	}<br />
</code></p>
<p>The second function, which is the guts of individual file backups looks like the following:<br />
<code><br />
sub doBackup<br />
	{<br />
		my $errors = "";<br />
		my $host     = "s3.amazonaws.com";<br />
		my $resource = $requestURI;<br />
		getResourceToSign($host, \$resource);</p>
<p>		my $httpDate = POSIX::strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime);<br />
		my $aclHeaderToSign = defined $acl ? "x-amz-acl:$acl\n" : "";<br />
		my $stringToSign = "$method\n$contentMD5\n$contentType\n$httpDate\n$aclHeaderToSign$resource";</p>
<p>		my $hmac = Digest::HMAC_SHA1->new($secretKey);<br />
		$hmac->add($stringToSign);<br />
		my $signature = encode_base64($hmac->digest, "");</p>
<p>		my @args = ();<br />
		push @args, ("-H", "\"Date: $httpDate\"");<br />
		push @args, ("-H", "\"Authorization: AWS $keyId:$signature\"");<br />
		push @args, ("-H", "\"x-amz-acl: $acl\"") if (defined $acl);<br />
		push @args, ("-H", "\"content-type: $contentType\"") if (defined $contentType);<br />
		push @args, ("-T", "\"$sourceFile\"") if (defined $sourceFile);</p>
<p>		push @args, "http://$host$requestURI";</p>
<p>		$cmd = "$curl -s @args";<br />
		open(CURL, "$cmd 2>&#038;1 |") || warn "can't open: $!";<br />
		local $SIG{PIPE}='IGNORE';<br />
		while(<curl>)<br />
		{<br />
			chomp($_);<br />
			#$errors.= "$_ ";<br />
			if($_ =~ m/.*\<code\>(.*)\<\/Code>.*/) {<br />
 				$errors = "Amazon Error Code $1";<br />
			}<br />
		}</p>
<p>		if($errors) {<br />
			$backup_retries  += 1;<br />
			$backup_comments = "Amazon errors: see log file";<br />
			$log->error(1, $logDir, ($SpawnID, $file_id, $user_id, $backup_id, "$errors") );<br />
		} else {<br />
			$continue = "true";<br />
		}</p>
<p>	}<br />
</code></p>
<p>I have some custom log objects in there that you probably want to remove in your own application. To make all this happen from your win32 platform you will obviously need perl with the following use statements:<br />
<code><br />
use POSIX;<br />
use Digest::HMAC_SHA1;<br />
use MIME::Base64 qw(encode_base64);<br />
use Getopt::Long qw(GetOptions);<br />
</code></p>
<p>You will also require a curl executable (full path should be in $curl). I'm currently using the version available <a href="http://curl.haxx.se/download.html">here</a>.</p>
<p>Then from the main body of your code you can call the doBackup function with something like this;<br />
<code><br />
my $curl        = "D:\\services\\scripts\\bin\\curl.exe";<br />
my $keyId       = "YOURKEYID";<br />
my $secretKey   = "YOURSECRETKEY";<br />
my $acl         = "public-read";<br />
$sourceFile = "\\\\$server_name\\$path\\$filename.$file_ext";<br />
$targetFile = "/$bucket_name/$path/$filename.$file_ext";<br />
$contentType = "image/jpeg"<br />
$requestURI = $targetFile;<br />
$method = "PUT"; #Can also use GET or DELETE<br />
&#038;doBackup();<br />
</code></p>
<p>I have all of the code in some sort of while loop which can then parse and process individual files on the win32 system along with some basic form of error checking and retry system. I catch $errors in the doBackup function as you inevitably get timeouts and so forth on the S3 side. I also make the corresponding code multithreaded so that I can have simultaneous threads processing file backups to S3 (I use up to 10 threads at a time depending how busy DPHOTO is).</p>
<p>Hope someone else finds this useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2007/using-perl-to-get-put-and-delete-on-amazon-s3-storage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using perl to read your win32 event log</title>
		<link>http://altentee.com/2007/using-perl-to-read-your-win32-event-log/</link>
		<comments>http://altentee.com/2007/using-perl-to-read-your-win32-event-log/#comments</comments>
		<pubDate>Mon, 06 Aug 2007 06:16:35 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[Altentee]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2007/using-perl-to-read-your-win32-event-log/</guid>
		<description><![CDATA[<p>I often use a combination of cygwin with ssh to remotely manage windows servers, as I find this to be a quicker (and hopefully safer) method of access to my windows boxes. To that end, I often need to check windows application event logs. Typically you&#8217;d use the mmc, but all I want to do [...]]]></description>
			<content:encoded><![CDATA[<p>I often use a combination of cygwin with ssh to remotely manage windows servers, as I find this to be a quicker (and hopefully safer) method of access to my windows boxes. To that end, I often need to check windows application event logs. Typically you&#8217;d use the mmc, but all I want to do mostly is check the last 10 or 100 entries for things like break in attempts, or application warnings/failures etc.</p>
<p><span id="more-283"></span><br />
To do that through your ssh session, you can use the native Win32::EventLog module that ships with the ActiveState version of Perl. I can&#8217;t remember where I got the majority of this code from, but I have since modified it to work within a Win32 environment along with some simple command line arguments. The version I copied was more in line with *ix systems I believe.</p>
<p>If I can remember where I got the code from I&#8217;ll  acknowledge it, but feel free to use my modified version in the interim <img src='http://altentee.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<code><br />
use Win32::EventLog;</p>
<p>$machine  = $ARGV[0] || "DEFAULTSERVERNAME";<br />
$eventlog = $ARGV[1] || "Application";<br />
$limit    = $ARGV[2] || 100;</p>
<p>my ($EventLog, $count, $first, $key);</p>
<p>$first = $count = 0;<br />
my $event={<br />
        'Source'              =>NULL,<br />
        'Computer'            =>NULL,<br />
        'Length'              =>NULL,<br />
        'Category'            =>NULL,<br />
        'RecordNumber'        =>NULL,<br />
        'TimeGenerated'       =>NULL,<br />
        'Timewritten'         =>NULL,<br />
        'EventID'             =>NULL,<br />
        'EventType'           =>NULL,<br />
        'ClosingRecordNumber' =>NULL,<br />
        'Strings'             =>NULL,<br />
        'Data',               =>NULL,<br />
        };</p>
<p>$EventLog = new Win32::EventLog( 'Application' ) || die $!;</p>
<p>$EventLog->GetOldest(\$first) || die $!;<br />
$EventLog->GetNumber(\$count) || die $!;</p>
<p>$EventLog->Read((EVENTLOG_SEEK_READ | EVENTLOG_BACKWARDS_READ),$first+$count,$event);</p>
<p>for $i ($first+$count-$limit+1..$first+$count)<br />
        {<br />
        $EventLog->Read((EVENTLOG_SEQUENTIAL_READ|EVENTLOG_BACKWARDS_READ),0,$event);<br />
        ($sec,$min,$hour,$mday,$mon,$year,$sday,$yday,$isdst) = localtime($event->{'TimeGenerated'});;</p>
<p>        #to get a readable EventId<br />
        $event->{'EventID'} = $event->{'EventID'} &#038; 0xffff;</p>
<p>        #foreach $key ('RecordNumber','Category','Source','Strings')<br />
        #       {<br />
        #       print sprintf( "%15s -> %s\n",$key, $event->{$key} );<br />
        #       }</p>
<p>        print "$mday/",$mon+1,"/",$year+1900,"\t$hour:$min\t".$event->{Strings}."\n";<br />
        }<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2007/using-perl-to-read-your-win32-event-log/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t forget Perl one liners</title>
		<link>http://altentee.com/2007/dont-forget-perl-one-liners/</link>
		<comments>http://altentee.com/2007/dont-forget-perl-one-liners/#comments</comments>
		<pubDate>Fri, 18 May 2007 00:42:19 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2007/dont-forget-perl-one-liners/</guid>
		<description><![CDATA[<p>If you have the requirement to manipulate multitudes of input messages / log files / data templates with dynamic variables, you may be left wondering what is the best approach. One could argue in a friendly way for hours about which language is the best to achieve this outcome (almost like pc vs. mac), but [...]]]></description>
			<content:encoded><![CDATA[<p>If you have the requirement to manipulate multitudes of input messages / log files / data templates with dynamic variables, you may be left wondering what is the best approach. One could argue in a friendly way for hours about which language is the best to achieve this outcome (almost like pc vs. mac), but since I often find myself working on mixed environments, you can&#8217;t go past perl one liners&#8230;</p>
<p><span id="more-277"></span><br />
To rehash what many others have already stated, here are my own favourites:</p>
<p>Print HEX value of a string good for encoding those MQMD headers. If you want to reverse use pack instead of unpack&#8230; You can also use B* for binary.<br />
<code>perl -e 'print unpack "H*", "AMQNUS725PQ"'<br />
</code></p>
<p>Replace 8 byte value which is offset at position 128 with the &#8216;NEWVALUE&#8217;:<br />
<code>perl -pi -e 'substr($_, 128, 8)="NEWVALUE"' /root/path/to/your/files/*<br />
</code></p>
<p>To copy posn 55 len 8 to posn 128 len 8:<br />
<code>perl -pi -e 'substr($_, 128, 8)=substr($_, 55, 8)' /root/path/to/your/files/*<br />
</code></p>
<p>To replace posn 128 len 8 in each file with first 8 bytes of the filename:<br />
<code>perl -pi -e 'substr($_,128,8)=substr($ARGV,0,8)' /root/path/to/your/files/*<br />
</code></p>
<p>To access your shell environment variables:<br />
<code>ACCOUNTF10=OUTSIDE<br />
perl -e 'print "I AM INSIDE MY EXPRESSION AND NOW I AM '$ACCOUNTF10' MUHAHAHAHA"'<br />
</code></p>
<p>To allow for variable interpolation, use double quoted strings which substitutes the value of a variable into a string:<br />
<code>perl -pi -e 'substr($_,6162,10)="'$PRODUCTEND'"' $OUTPUTFILEFULL<br />
</code></p>
<p>Global search and replace using regex for search string (could also use fixed values instead of regex):<br />
<code>search="2007[0-9]{4}"<br />
replace="20070321"<br />
perl -pi -e 's/'$search'/'$replace'/g' /root/path/to/your/files/*<br />
</code></p>
<p>Find alternate search values and replace them with a single value:<br />
<code>search="KENANR|SIEBEL"<br />
replace="SIEBEL"<br />
perl -pi -e 's/'$search'/'$replace'/g' /root/path/to/your/files/*<br />
</code></p>
<p>Find anything that starts with a search value and replace them with a single value (Notice I pad strings out as the application in use depends on fixed format):<br />
<code>search="^Christina"<br />
replace="Timothy   "<br />
perl -pi -e 's/'$search'/'$replace'/g' /root/path/to/your/files/*<br />
</code></p>
<p>Find anything that ends with a search value and replace them with a single value:<br />
<code>search="Bank Deposit$"<br />
replace="Bank Credit  "<br />
perl -pi -e 's/'$search'/'$replace'/g' /root/path/to/your/files/*<br />
</code></p>
<p>Transliteration (swaps characters around) of specific characters:<br />
<code>search="cd"<br />
replace="dc"<br />
perl -pi -e 'tr/'$search'/'$replace'/' /root/path/to/your/files/*<br />
</code></p>
<p>And here are some metacharaters/character classes you can use in your search strings if you don&#8217;t want to use literals:<br />
<code>[a-z]    any charater between a to z<br />
[A-Z]    any charater between A to Z<br />
[0-9]    any number between 0 to 9<br />
\d       same as [0-9]<br />
\D       inverse of [0-9] ie. any non digit<br />
\w       same as [a-zA-Z0-9_]<br />
\W       inverse of \w<br />
\s       same as [ \r\t\n\f] ie. any white space<br />
\S       inverse of \s<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2007/dont-forget-perl-one-liners/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Monitoring queue statistics in MQ</title>
		<link>http://altentee.com/2007/monitoring-queue-statistics-in-mq/</link>
		<comments>http://altentee.com/2007/monitoring-queue-statistics-in-mq/#comments</comments>
		<pubDate>Mon, 30 Apr 2007 05:55:43 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[MQ]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2007/monitoring-queue-statistics-in-mq/</guid>
		<description><![CDATA[<p>When load testing MQ you are no doubt going to need to be able to monitor queue statistics in terms of how many messages have been enqueued and dequeued within a given timeframe. You can use native runmqsc commands to query queues in order to find current queue depths but this is just a snapshot [...]]]></description>
			<content:encoded><![CDATA[<p>When load testing MQ you are no doubt going to need to be able to monitor queue statistics in terms of how many messages have been enqueued and dequeued within a given timeframe. You can use native <b>runmqsc</b> commands to query queues in order to find current queue depths but this is just a snapshot in time. In order to be able to monitor how many messages have been or gone, you need to sample the queue over time.  Here is a good <a href="http://www.mqseries.net/phpBB2/viewtopic.php?p=112759">synopsis</a> of options&#8230;</p>
<p>A good way to achieve this is my using the <a href="http://www-1.ibm.com/support/docview.wss?rs=203&#038;uid=swg24000668&#038;loc=en_US&#038;cs=utf-8&#038;lang=en">PCF support package</a> provided by IBM.</p>
<blockquote><p>The WebSphere MQ Programmable Command Formats (PCF) provide the capability to perform administration tasks on a queue manager by sending and receiving WebSphere MQ messages of a special format. PCF request messages are sent to the queue manager&#8217;s command queue, where they are processed by the command server and replies returned to the designated reply-to queue.</p>
<p>This SupportPac contains a set of Java classes representing PCF header structures as well as an agent that can be used to simplify the task of communicating with a target queue manager and thus enable the use of WebSphere MQ Programmable Command Formats for queue manager administration. </p></blockquote>
<p>Using a simple java object as documented in <a href="http://www-304.ibm.com/jct09002c/isv/tech/sample_code/mq/ResetQStats.java">sample</a> code, you can query queue stats of your choice. My implementation simply prints out the queue you are connected to, along with enqueue, dequeue and total queue size stats over an arbitrary time frame (eg. last 2 seconds). This can easily be called from a simple shell script.</p>
<p><span id="more-273"></span><br />
<b>ResetQStats.java</b><br />
<code><br />
/**<br />
* Reset MQ Queue Statistics (ResetQStats)<br />
*<br />
* Compile	: javac -classpath com.ibm.mq.jar:connector.jar:jta.jar:com.ibm.mq.pcf-6.0.jar ResetQStats.java</p>
<p>* Package	: jar cfm ResetQStats.jar ResetQStats.MF *.class<br />
* Execute	: java -cp com.ibm.mq.jar:connector.jar:jta.jar:com.ibm.mq.pcf-6.0.jar:ResetQStats.jar ResetQStats [options]<br />
* Usage		: ResetQStats [options]<br />
* Options	:<br />
		host		MQ hostname eg. 127.0.0.1<br />
		port		      MQ port eg. 1415<br />
		channel		MQ channel eg. CHANNEL_NAME<br />
		queue		MQ queue eg. QUEUE_NAME<br />
*<br />
* Last edited	: 6 Mar 07 14.00<br />
* Author		: Tim Koopmans<br />
**/</p>
<p>import java.io.*;<br />
import com.ibm.mq.*;<br />
import com.ibm.mq.pcf.*;</p>
<p>public class ResetQStats<br />
{<br />
	final public static String copyright =<br />
                  "Copyright (c) IBM Corp. 2005 All rights reserved.";</p>
<p>	public static void main (String [] args)<br />
	{<br />
           PCFAgent 		 agent;<br />
		PCFParameter [] parameters = { new MQCFST (CMQC.MQCA_Q_NAME,args [3]) };<br />
		MQMessage [] 	 responses;<br />
		MQCFH 			 cfh;<br />
		PCFParameter 	 p;</p>
<p>		try<br />
		{<br />
		   	// Connect a PCFAgent to the specified queue manager<br />
			if (args.length == 1)<br />
			{<br />
				agent = new PCFAgent (args [0]);<br />
			}<br />
			else<br />
			{<br />
				agent = new PCFAgent (args [0], Integer.parseInt (args [1]), args [2]);<br />
			}</p>
<p>			// Use the agent to send the request</p>
<p>			responses = agent.send (CMQCFC.MQCMD_RESET_Q_STATS, parameters);<br />
			cfh = new MQCFH (responses [0]);</p>
<p>			if (cfh.reason == 0)<br />
			{<br />
				//System.out.println ("Queue Statistics:");<br />
				for (int i = 0; i < cfh.parameterCount; i++)<br />
				{<br />
					// Walk through the returned attributes<br />
					p = PCFParameter.nextParameter (responses [0]);<br />
					int parm = p.getParameter();<br />
					switch (parm)<br />
					{<br />
						case CMQC.MQCA_Q_NAME:<br />
									        //Queue Name<br />
									        break;<br />
						case CMQC.MQIA_TIME_SINCE_RESET:<br />
									        //TimeSinceReset t(sec)<br />
									        break;<br />
						case CMQC.MQIA_MSG_ENQ_COUNT:<br />
									        //MsgEnqCount ++<br />
										  break;<br />
						case CMQC.MQIA_MSG_DEQ_COUNT:<br />
									        //MsgDeqCount --										  break;<br />
						case CMQC.MQIA_HIGH_Q_DEPTH:<br />
									        //HighQDepth  (total)<br />
										  break;<br />
					}<br />
					System.out.print(" \t" + p.getValue ());<br />
				}<br />
				System.out.print("\n");<br />
			}<br />
			else<br />
			{<br />
				System.out.println ("PCF error:\n" + cfh);<br />
				// Walk through the returned parameters describing the error<br />
				for (int i = 0; i < cfh.parameterCount; i++)<br />
				{<br />
					System.out.println (PCFParameter.nextParameter (responses [0]));<br />
				}<br />
			}</p>
<p>			// Disconnect<br />
			agent.disconnect ();<br />
		}</p>
<p>		catch (ArrayIndexOutOfBoundsException abe)<br />
		{<br />
			System.out.println ("Usage: \n" +<br />
				"\tjava ResetQStats queue-manager\n" +<br />
				"\tjava ResetQStats host port svrconn-channel");<br />
		}</p>
<p>		catch (NumberFormatException nfe)<br />
		{<br />
			System.out.println ("Invalid port: " + args [1]);<br />
			System.out.println ("Usage: \n" +<br />
				"\tjava ResetQStats queue-manager\n" +<br />
				"\tjava ResetQStats host port svrconn-channel");<br />
		}</p>
<p>		catch (MQException mqe)<br />
		{<br />
			System.err.println (mqe);<br />
		}</p>
<p>		catch (IOException ioe)<br />
		{<br />
			System.err.println (ioe);<br />
		}<br />
	}<br />
}<br />
</code></p>
<p><b>Simple Shell Script</b><br />
<code><br />
#~/bin/sh<br />
javac -classpath $HOME/harness/CDE/com.ibm.mq.jar:$HOME/harness/CDE/connector.jar:$HOME/harness/CDE/jta.jar:/home/strata/d281447/harness/CDE/com.ibm.mq.pcf-6.0.jar $HOME/harness/CDE/ResetQStats.java<br />
cd $HOME/harness/CDE<br />
jar cfm ResetQStats.jar ResetQStats.MF *.class<br />
rm $HOME/harness/CDE/*.class</p>
<p>cd $HOME/harness/CDE</p>
<p>printf "\tQueue Name\t\t\t\t\t\t++ \t-- \tdepth \tsecs\n"</p>
<p>duration=$2	#duration in seconds<br />
sampleRate=$3 	#sample every n seconds</p>
<p>i="1"<br />
while [ $i -le $duration ]<br />
do<br />
	java -cp com.ibm.mq.jar:connector.jar:jta.jar:com.ibm.mq.pcf-6.0.jar:ResetQStats.jar ResetQStats 127.0.0.1 1415 CHANNEL $1</p>
<p>	sleep $sampleRate<br />
	i=`expr $i + 1`</p>
<p>done<br />
printf "\n"<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2007/monitoring-queue-statistics-in-mq/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Perl of an idea for try &#8230; catch clauses</title>
		<link>http://altentee.com/2007/a-perl-of-an-idea-for-try-catch-clauses/</link>
		<comments>http://altentee.com/2007/a-perl-of-an-idea-for-try-catch-clauses/#comments</comments>
		<pubDate>Tue, 02 Jan 2007 23:20:50 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2007/a-perl-of-an-idea-for-try-catch-clauses/</guid>
		<description><![CDATA[<p>The try&#8230;catch&#8230;finally clause found in languages like Java are very handy for error handling. In scripting languages like Perl you can achieve the same effect using the eval function as the following code snippet demonstrates.</p>
<p>
eval{ &#038;yourSubRoutine($parameters); };
$@ ?  $yourLogObject->yourErrorMethod("I failed with reason: $@") ):
     $yourLogObject->yourTraceMethod("Everything was good: $?") );
</p>
]]></description>
			<content:encoded><![CDATA[<p>The try&#8230;catch&#8230;finally clause found in languages like Java are very handy for error handling. In scripting languages like Perl you can achieve the same effect using the eval function as the following code snippet demonstrates.</p>
<p><code><br />
eval{ &#038;yourSubRoutine($parameters); };<br />
$@ ?  $yourLogObject->yourErrorMethod("I failed with reason: $@") ):<br />
     $yourLogObject->yourTraceMethod("Everything was good: $?") );<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2007/a-perl-of-an-idea-for-try-catch-clauses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
