Perl (difference between windows and linux) - windows

I use the following Perl code without any problems in Ubuntu, but when I try it in XP using activeperl it hangs, no error messages, just a blank screen. Are there any issues I should be aware of when moving code between standard perl and active perl or windows and ubuntu?
*sub do_search
{
my $term = shift #_;
my $page = 1;
my #results;
while (scalar #results < $opts{maxresults})
{
my $rset = $handle->search({query=>$term, page => $page, rpp => $opts{rpp} });
print "Searching for $term (page $page)\n" if $opts{verbose};
if (ref $rset eq 'HASH' && exists $rset->{results})
{
# break out if no results came back
last unless #{$rset->{results}};
push #results, #{$rset->{results}};
printf "Now we have %d entries\n", scalar #results if $opts{verbose};
}
# go to the next page
$page++;
}
print_post($_) foreach #results;
}*
source:http://www.ibm.com/developerworks/web/library/l-perl-twitter/index.html
-Thanks

There is quite extensive manual page about Windows-specific perl problems - perlwin32.
Only non-core package the script is using is Net::Twitter, which seems to have good test results under Windows - platform test matrix.

Related

Perl Net::MAC::Vendor OUI

The follow is on MacOS High Sierra with Perl v5.28.2. The version of Net::MAC::Vendor is 1.265. This sort of a repeat post. My prior post lacked a lot of detail.
I am trying to put together a script to list ip addresses, MAC addresses, and vendors on a network. The Net::MAC::Vendor::lookup function is returning a timeout error amongst other things. I have checked a few IEEE links that were supposed to have the OUI data but they are all dead returning no data. I have seen a number of mentions stating the file can be found in some installations of linux. I have search high and low and have not found an oui.txt file on my system. If I downloaded a copy I wouldn't know where to put it or how I could have the Net::MAC::Vendor function to locate it. Also, if I did find a link I still wouldn't know how to direct the vendor lookup function to use it.
The errors I am getting are as follows:
Use of uninitialized value in concatenation (.) or string at /Users/{username}/perl5/perlbrew/perls/perl-5.28.2/lib/site_perl/5.28.2/Net/MAC/Vendor.pm line 320.
Failed fetching [https://services13.ieee.org/RST/standards-ra-web/rest/assignments/download/?registry=MA-L&format=html&text=D8-D7-75] HTTP status []
message [Connect timeout] at simplemacvendor.pl line 23.
Could not fetch data from the IEEE! at simplemacvendor.pl line 23.
The sample code:
#!/usr/bin/perl;
use strict;
use feature qw(say);
use Data::Dumper qw(Dumper);
use Net::MAC::Vendor;
open(ARP, "arp -na|") || die "Failed $!\n";
my #arp_table;
while (<ARP>) {
if ($_ =~ m/incomplet/) {next;}
if ($_ =~ m/Address/) {next;}
my #line = split(' ',$_);
my $computer = {};
$line[1] =~ s/(\()([0-9\.]*)(\))/\2/;
$computer->{ip} = $line[1];
$computer->{mac} = $line[3];
$computer->{if} = $line[5];
say Dumper($computer);
# Get vendor info
my $vendor_info = Net::MAC::Vendor::lookup( $computer->{mac} ); # line 23
$computer->{vendor} = $vendor_info->[0];
push #arp_table , $computer;
}
print "ARP Table with vendors:\n";
for my $i (0 .. $#arp_table) {
print "$arp_table[$i]{ip}\t";
print "$arp_table[$i]{if}\t";
print "$arp_table[$i]{mac}\t";
print "$arp_table[$i]{vendor}";
print "\n";
}

Why does the Perl app 'prove' launch my scripts in parallel but not execute test cases within those scripts in parallel?

I've got a couple of .t files in a folder. Each test script launches its own instance of Selenium and therefore opens its own browser. These then pass their instructions to page objects in separate modules. The page objects are where most of the test assertions occur, alas.
I run them in parallel using prove -j2 testfolder. When I do this I see two browsers open, responding to the Selenium calls, but the test results and browser action indicate that the second script only goes as far as just before the first script's first call to Test::More, then it hangs until the first script has finished.
The page object model is a red herring. I've tried just putting bare pass() calls at the top of each .t file and confirmed that the test case in the second script isn't tried until the entire first script is completed.
Each testX.t file ends up looking something like this:
use strict;
use warnings;
use Test::More tests => 40;
use Selenium::Remote::Driver;
use MyPage::Object; # test execution module
my $sel = new Driver( 'browser_name' => $browser,'
'remote_server_addr' => $host,
'port' => "80", );
pass("Debug test case - let's see when this passes");
my $user = new MyPage::Object( text => "test string", sel => $sel);
$user->verify_text;
.
.
Here's what Object.pm looks like:
use strict;
use warnings;
use Selenium::Remote::Driver;
use Selenium::Remote::WebElement qw(get_text);
package Object;
sub new {
my $class = shift;
my $self = bless { #_ }, $class;
return $self;
}
sub verify_text {
my ($self, $text_to_verify) = #_;
my $webElement = $self->{sel}->find_element("//*$xpath") or warn $!;
my $returnedtext = get_text($webElement) or warn $!;
Test::More::ok($returnedtext =~ /\Q$text_to_verify/, "text matches");
}
1;
Here's the output. While the first test is running I see this:
===( 4;12 4/40 0/? )===========================================
The first pair of numbers and the left number in the second pair go up as the first script's test cases are verified. After this, when the second script starts, the output changes to this:
testfolder\test2.t .. 4/35
With the left number increasing as test cases are executed.
Shouldn't running these in parallel cause the assertions in each of them to be run at the same time? Is this unusual or is this how parallel jobs are supposed to work in prove?
I'm running this from the command line in 64-bit Windows 7, ActiveState Perl v5.16.1. CPAN shows Prove is up to date (3.28).
I came up with a workaround, though this isn't really a solution to the root issue. I used a combo of this solutions at the Sauce Labs blog and Freddy Vega's solution here to come up with this:
#!usr/bin/perl
use strict;
use warnings;
use File::Find::Rule;
use Thread::Pool::Simple;
my $count = 0;
my #files = File::Find::Rule->file()
->name( '*.t' )
->in( 'C:\path\to\tests\' );
sub worker() {
my $file = shift;
system("prove $file");
print "Executing Test: " . $file . "\n";
}
my $pool = Thread::Pool::Simple->new(
min => 5,
max => 25,
do => [\&worker],
);
foreach my $test (#files) {
$pool->add($test);
print "Added $test to pool..\n";
$count++;
}
$pool->join();
exit(0);

perl large IO bug on Mac but not Windows or Linux (adds newline can't be chomped)

I've tested my program on a dozen Windows machines, a half dozen Macs, and a Linux machine and it works without error on both the Windows and Linux but not the Macs. My program is designed to work with protein database files which are text files that range from 250MB to 10GB. I took 1/10th of the 250MB file to make a sample file for debugging purposes but found that the error did not occur with the smaller file.
I've narrowed down the bug to this section of code, in this section $tempFile, is the protein database file:
open(ps_file, "..".$slash."dataset".$slash.$tempFile)
or die "couldn't open $tempFile";
while(<ps_file>){
chomp;
my #curLine = split(/\t/, $_);
my $filter = 1;
if($taxon){
chomp($curLine[2]);
print "line2 ".$curLine[2].",\t".$taxR{$curLine[2]}."\n";
$filter = $taxR{$curLine[2]};
}
if($filter){
checkSeq(#curLine);
}
}
This is a screenshot of the output of that print statement showing special characters:
This is what the output looks like on a Windows Machine:
Here is an example of 1 line from the $tempFile
>sp|P48255|ABCX_CYAPA Probable ATP-dependent transporter ycf16 OS=Cyanophora paradoxa GN=ycf16 PE=3 SV=1 MSTEKTKILEVKNLKAQVDGTEILKGVNLTINSGEIHAIMGPNGSGKSTFSKILAGHPAYQVTGGEILFKNKNLLELEPEERARAGVFLAFQYPIEIAGVSNIDFLRLAYNNRRKEEGLTELDPLTFYSIVKEKLNVVKMDPHFLNRNVNEGFSGGEKKRNEILQMALLNPSLAILDETDSGLDIDALRIVAEGVNQLSNKENSIILITHYQRLLDYIVPDYIHVMQNGRILKTGGAELAKELEIKGYDWLNELEMVKK CYAPA
The problem probably lies in inconsistent line-endings. If, as I suspect, trailing whitespace is not significant, you're better off removing that instead of chomping.
Also note:
Bareword filehandles such as ps_file are package global variables that are subject to action at a distance, use lexical filehandles.
Use File::Spec or Path::Class to handle file paths in a platform independent way.
Include full file paths and error message if there is an error opening a file.
In
chomp;
my #curLine = split(/\t/, $_);
my $filter = 1;
if($taxon){
chomp($curLine[2]);
$curLine[2] comes from a string that was read in as a line and chomped. I don't see why you are chomping that again.
Here's tidied up version of your code-snippet:
use File::Spec::Functions qw( catfile );
my $input_file = catfile('..', dataset => $tempFile);
open my $ps_file, '<', $input_file
or die "couldn't open '$input_file': $!";
while (my $line = <$ps_file>) {
$line =~ s/\s+\z//; # remove all trailing space
my #curLine = split /\t/, $line;
my $filter = 1;
if ($taxon) {
my $field = $curLine[2];
$filter = $taxR{ $field };
print join("\t", "line2 $field", $filter), "\n";
}
if ($filter) {
checkSeq(#curLine);
}
}

How can I automate an existing instance of Internet Explorer using Perl?

I am struggling to get control of an IE preview control which is 'Internet Explorer_Server' class on an external windows application with perl.
Internet Explorer_Server is the class name of the window, I've found it with Spy++. and here’s my assertion code of it
$className = Win32::GUI::GetClassName($window);
if ($className eq "Internet Explorer_Server") {
...
}
I can get a handle of that 'Internet Explorer_Server' with Win32::GUI::GetWindow, but have no idea what to do next.
Updated: You are going down the wrong path. What you need is Win32::OLE.
#!/usr/bin/perl
use strict;
use warnings;
use Win32::OLE;
$Win32::OLE::Warn = 3;
my $shell = get_shell();
my $windows = $shell->Windows;
my $count = $windows->{Count};
for my $item ( 1 .. $count ) {
my $window = $windows->Item( $item );
my $doc = $window->{Document};
next unless $doc;
print $doc->{body}->innerHTML;
}
sub get_shell {
my $shell;
eval {
$shell = Win32::OLE->GetActiveObject('Shell.Application');
};
die "$#\n" if $#;
return $shell if defined $shell;
$shell = Win32::OLE->new('Shell.Application')
or die "Cannot get Shell.Application: ",
Win32::OLE->LastError, "\n";
}
__END__
So, this code finds a window with a Document property and prints the HTML. You will have to decide on what criteria you want to use to find the window you are interested in.
ShellWindows documentation.
You may want to have a look at Win32::IE::Mechanize. I am not sure whether you can control an existing IE window with this module, but accessing a single URL should be possible in about five lines of code.
Have you looked at Samie http://samie.sourceforge.net/ as this is a perl module to control IE

How can I get forking pipes to work in Perl on Windows?

I'm trying to port a Perl script over from Unix to Windows but am having a near impossible time getting it to work due to the unsupported forking pipes in the open function. Here's the code:
sub p4_get_file_content {
my $filespec = shift;
return 'Content placeholder!' if ($options{'dry-run'});
debug("p4_get_file_content: $filespec\n");
local *P4_OUTPUT;
local $/ = undef;
my $pid = open(P4_OUTPUT, "-|");
die "Fork failed: $!" unless defined $pid;
if ($pid == 0) { # child
my $p4 = p4_init();
my $result = undef;
$result = $p4->Run('print', $filespec);
die $p4->Errors() if $p4->ErrorCount();
if (ref $result eq 'ARRAY') {
for (my $i = 1; $i < #$result; $i++) {
print $result->[$i];
}
}
$p4->Disconnect();
exit 0;
}
my $content = <P4_OUTPUT>;
close(P4_OUTPUT) or die "Close failed: ($?) $!";
return $content;
}
The error is:
'-' is not recognized as an internal or external command,
operable program or batch file.
Does anyone know how to make this work? Thanks!
Mike
I know it's not a direct answer to your question, but it looks like you're scripting something on top of Perforce in Perl? If so you might find an existing library does what you want already and save yourself a lot of headaches, or at least give you some sample code to work from.
For example:
P4Perl
P4::Server
P4::C4
EDIT: Now that I know what you're doing I'm guessing you're trying to port p42svn to Windows, or rather make it compatible with Windows at least. See this thread for a discussion of this exact issue. The recommendation (untested) is to try the code samples listed at http://perldoc.perl.org/perlfork.html under "Forking pipe open() not yet implemented" to explicitly create the pipe instead.
It's not going to work as-is. You'll need to find another method to accomplish what it's doing. It doesn't look like there's that burning a need for the fork-pipe, but it's hard to tell since I don't know what a p4 is and a lot of your code is being lost to angle bracket interpretation.

Resources