I am trying to run a perl script 'googly.pl' from the command line, and it is giving some errors. Here is the script and the errors. I have re-checked the script, but I am still unable to successfully run the script.
#!C:\Strawberry\perl\bin\perl.exe
# googly.pl
# A typical Google Web API Perl script
# Usage: perl googly.pl <query>
# Your Google API developer's key
my $google_key='';
# Location of the GoogleSearch WSDL file
my $google_wdsl = "C:/vhosts/phpcs5/GoogleSearch.wsdl";
use strict;
# Use the SOAP::Lite Perl module
use SOAP::Lite;
# Take the query from the command-line
my $query = shift #ARGV or die "Usage: perl googly.pl
<query>\n";
# Create a new SOAP::Lite instance, feeding it
GoogleSearch.wsdl
my $google_search = SOAP::Lite->service("file:$google_wdsl");
# Query Google
my $results = $google_search ->
doGoogleSearch(
$google_key, $query, 0, 10, "false", "", "false",
"", "latin1", "latin1"
);
# No results?
#{$results->{resultElements}} or exit;
# Loop through the results
foreach my $result (#{$results->{resultElements}}) {
# Print out the main bits of each result
print
join "\n",
$result->{title} || "no title",
$result->{URL},
$result->{snippet} || 'no snippet',
"\n";
}
Errors
Semicolon seems to be missing at C:/vhosts/phpcs5/googly.pl line 19.
Syntax error at C:/vhosts/phpcs5/googly.pl line 17, near "wsdl my "
Global symbol "$google_search" requires explicit package name at C:/vhosts/phpcs5/googly.pl line 17
Global symbol "$google_search" requires explicit package name at C:/vhosts/phpcs5/googly.pl line 19
Syntax error at C:/vhosts/phpcs5/googly.pl line 20, near "doGoogleSearch"
Execution of C:/vhosts/phpcs5/googly.pl aborted due to compilation errors.
my $query = shift #ARGV or die "Usage: perl googly.pl
<query>\n";
# Create a new SOAP::Lite instance, feeding it
GoogleSearch.wsdl
my $google_search = SOAP::Lite->service("file:$google_wdsl");
should be
my $query = shift #ARGV or die "Usage: perl googly.pl <query>\n";
# Create a new SOAP::Lite instance, feeding it GoogleSearch.wsdl
my $google_search = SOAP::Lite->service("file:$google_wdsl");
Related
Hopefully you can help a scientist to decipher whats wrong with the code I'm trying to run to clean up some NGS results. The Perl file itself comes from https://github.com/mtokuyama/ERVmap, though I am posting the code below for reference. The other Perl files in the package work just fine and, while I have built a passing ability to use the linux terminal, Perl is a little beyond me.
The linux terminal I'm using is currently running: Ubuntu 16.04.6 LTS
This is the Perl code I'm trying to run using the following command line on linux as instructed by their GitHub page:
perl clean_htseq.pl ./ c c2 __
#!/usr/bin/env perl
#$Id: run_clean_htseq.pl,v 1.2 2015/03/02 17:24:35 yk336 Exp $
#
# create pbs file
#
use warnings;
use strict;
use File::Basename;
use POSIX;
my $dir = shift;
my $e1 = shift;
my $e2 = shift;
my $stop = shift;
die "$e1 eq $e2" if ($e1 eq $e2);
my $find = "find $dir -name \"*${e1}\"";
my $out = `$find`;
my #files = split(/\n/, $out);
for my $f (#files) {
my $o = $f;
$o =~ s/${e1}$/$e2/;
my $cmd = "./clean_htseq.pl $stop $f > $o";
print "$cmd\n";
system($cmd);
}
The first error that I had was that the _clean_htseq.pl_ wasn't found (line 30, already altered to solution) which i solved by adding the ./ in front of it and giving the software permission to use the script file.
My current issue with the code/command line is the following error:
Use of uninitialized value $e2 in string eq at ./clean_htseq.pl line 18.
find: warning: Unix filenames usually don't contain slashes (though pathnames do). That means that '-name ‘*./SRR7251667.c’' will probably evaluate to false all the time on this system. You might find the '-wholename' test more useful, or perhaps '-samefile'. Alternatively, if you are using GNU grep, you could use 'find ... -print0 | grep -FzZ ‘*./SRR7251667.c’'.
This has been tracked down to the "__" at the end of the command line, while i'm sure this is supposed to mean something to the script I removed it and resulted in the following error:
Use of uninitialized value $stop in concatenation (.) or string at clean_htseq.pl line 30.
./clean_htseq.pl ./SRR7251667.c > ./SRR7251667.c2
Use of uninitialized value $e1 in string eq at ./clean_htseq.pl line 18.
Use of uninitialized value $e2 in string eq at ./clean_htseq.pl line 18.
Use of uninitialized value $e1 in concatenation (.) or string at ./clean_htseq.pl line 18.
Use of uninitialized value $e2 in concatenation (.) or string at ./clean_htseq.pl line 18.
eq at ./clean_htseq.pl line 18.
An error occurs too when I remove the "." from "./" but it comes back with an error about not finding the _clean_htseq.pl_ file which is in the working directory.
Your problem seems to be here:
my $dir = shift;
my $e1 = shift;
my $e2 = shift;
my $stop = shift;
Outside of a subroutine, shift works on #ARGV—the array that holds the command line arguments. You shift four times, so you need four arguments:
perl clean_htseq.pl ./ c c2 __
You only seem to give it two, and $stop has no value (so you are giving it less than two):
./clean_htseq.pl $stop $f
You can't just remove arguments and hope things still work out. Likely you're going to have to look at the source to see what those things mean (which should motivate you as a scientist to use good variable names and document code—Best Practices for Scientific Computing).
A first step may be to set defaults. The defined-or operator does well here:
use v5.10;
my $dir = shift // 'default_dir';
my $e1 = shift // 'default_value';
my $e2 = shift // 'default_value';
my $stop = shift // 'default_value';
Or, you could just give up if there aren't enough arguments. An array in scalar context gives you the number of elements in the array (although it doesn't guarantee anything about their values):
die "Need four arguments!\n" unless #ARGV == 4;
There are various other improvements which would help this script, some of which I go through in the "Secure Programming Techniques" chapter in Mastering Perl. Taking unchecked user input and passing it to another program is generally not a good idea.
I get the following error:
Use of uninitialized value $_ in concatenation (.) or string at checkfornewfiles.pl line 34.
when attempting to run the following code :
#!/usr/bin/perl -w
#Author: mimo
#Date 3/2015
#Purpose: monitor directory for new files...
AscertainStatus();
######### start of subroutine ########
sub AscertainStatus {
my $DIR= "test2";
####### open handler #############
opendir (HAN1, "$DIR") || die "Problem: $!";
########## assign theoutput of HAN1 to array1 ##########
my #array1= readdir(HAN1);
######## adding some logic #########
if ("$#array1" > 1) { #### if files exists (more than 1) in the directory #######
for (my $i=0; $i<2; $i++) {shift #array1;} ####### for i in position 0 (which is the . position) loop twice and add one (the position ..) get rid of them #######
MailNewFiles(#array1);
} else { print "No New Files\n";}
}
sub MailNewFiles {
$mail= "sendmail";
open ($mail, "| /usr/lib/sendmail -oi -t" ) ||die "errors with sendmail $!"; # open handler and pipe it to sendmail
print $mail <<"EOF"; #print till the end of fiEOF
From: "user";
To: "root";
Subject: "New Files Found";
foreach (#_) {print $mail "new file found:\n $_\n";}
EOF
close($mail);
}
#End
I am new to perl and I don't know what's going wrong. Can anyone help me ?
A few suggestions:
Perl isn't C. Your main program loop shouldn't be a declared subroutine which you then execute. Eliminate the AscertainStatus subroutine.
Always, always use strict; and use warnings;.
Indent correctly. It makes it much easier for people to read your code and help analyze what you did wrong.
Use a more modern Perl coding style. Perl is an old language, and over the years new coding style and techniques have been developed to help you eliminate basic errors and help others read your code.
Don't use system commands when there are Perl modules that can do this for you in a more standard way, and probably do better error checking. Perl comes with the Net::SMTP that handles mail communication for you. Use that.
The error Use of uninitialized value $_ in concatenation (.) or string is exactly what it says. You are attempting to use a value of a variable that hasn't been set. In this case, the variable is the #_ variable in your foreach statement. Your foreach isn't a true foreach, but part of your print statement since your EOF is after your for statement. This looks like an error.
Also, what is the value of #_? This variable contains a list of values that have been passed to your subroutine. If none are passed, it will be undefined. Even if #_ is undefined, foreach (undef) will simply skip the loop. However, since foreach (#_) { is a string to print, your Perl program will crash without #_ being defined.
If you remove the -w from #!/usr/bin/perl, your program will actually "work" (Note the quotes), and you'll see that your foreach will literally print.
I do not recommend you not to use warnings which is what -w does. In fact, I recommend you use warnings; rather than -w. However, in this case, it might help you see your error.
You have EOF after the line with foreach. It contains $_ which is interpolated here but $_ is not initialized yet because it is not in foreach loop. It is not code but just text. Move EOF before foreach.
But probably you would like
sub MailNewFiles {
$mail= "sendmail";
open ($mail, "| /usr/lib/sendmail -oi -t" ) ||die "errors with sendmail $!"; # open handler and pipe it to sendmail
local $"="\n"; # " make syntax highlight happy
print $mail <<"EOF"; #print till the end of fiEOF
From: "user";
To: "root";
Subject: "New Files Found";
New files found:
#_
EOF
close($mail);
}
See perlvar for more informations about $".
The message
Use of uninitialized value $xxx in ...
is very straightforward. When you encounter it, it means that you are using a variable ($xxx) in any way, but that the variable has not ever been initialized.
Sometimes, adding an initialization command at the start of you code is enough :
my $str = '';
my $num = 0;
Sometimes, your algorithm is wrong, or you just mistyped your variable, like in :
my $foo = 'foo';
my $bar = $ffo . 'bar'; # << There is a warning on this line
# << because you made a mistake on $foo ($ffo)
Hi below is my perl code :
#!/usr/bin/perl -w
no warnings;
use Env;
my $p4user = $ENV{'P4USER'};
my $current_path = $ENV{'PWD'};
print("\t Hello $p4user. You are currently in $current_path path.\n");
open($user_in,"$ARGV[0]") || die("failed to open the argument file $ARGV[0]\n");
print("\t To create a new client enter '1' |");
print("\t To use an existing client enter '2' : ... ");
my $cl_op = <>;
chop($cl_op);
if (($cl_op == 1) || ($cl_op == 2))
{
# do something common for both condition
if ($cl_op == 1)
{
# do something
}
elsif ($cl_op == 2)
{
# do something
}
}
else
{
die("\n\t Sorry. Invalid option : $cl_op\n");
}
Then the script runs like :
Hello biren. You are currently in /remote/vgvips18/biren/tcf_4nov path.
Sorry. Invalid option : ###################################################################
To create a new client enter '1' | To use an existing client enter '2' : ...
Any Idea why the script is behaving like this. When I comment out this line "
open($user_in,"$ARGV[0]") || die("failed to open the argument file
$ARGV[0]\n");
", the script runs fine.
Can anyone help why the script behaves when i pass a file as an argument on command line.
my $cl_op = <>;
That will read the first line of the file you passed as the arg.
To make it read the user response to your prompt, change it to this:
my $cl_op = <STDIN>;
It's wise to include sanity checks to verify that a file name was passed as an argument before attempting to open it.
my $user_in;
if ( defined $ARGV[0] ) {
die "$ARGV[0] does not exist.\n" unless -e $ARGV[0];
open($user_in,"$ARGV[0]")
or die("failed to open the argument file $ARGV[0]: $!\n");
}
<> is shorthand for <ARGV>, where ARGV is a special (i.e., magic) filehandle that can either mean filenames from your command-line arguments, or STDIN if there are no command-line arguments. Perl will make the decision how to treat ARGV based on the contents of #ARGV the first time it is used.
If you want invocations of your program like
perl my_script.pl userfile inputfile
perl my_script.pl userfile < inputfile
cat inputfile | perl my_script.pl userfile
to all work alike, you will want to consume the first element of #ARGV before you refer to ARGV. Like so:
my $userfile = shift #ARGV; # removes $ARGV[0] from front of #ARGV
open $user_in, '<', $userfile or ...
...
my $cl_op = <>;
Now $cl_op is being read from the second filename you provide, or from STDIN.
I am trying to create a .exe in perl. It works fine until I try to compile it into an exe. I am using Komodo IDE 5. I have posted my script and the error below. I have added the modules, LWP::UserAgent, NET, and Google::Voice and it still doesnt work. I use perlapp to create the .exe
#!/usr/bin/perl -w
use strict;
use warnings;
use Google::Voice;
use Date::Calc qw(Delta_Days);
use Net::Twitter;
#Set Days
my #today = (localtime)[5,4,3];
$today[0] += 1900;
$today[1]++;
my #RT = (2012, 7, 7);
my $days = Delta_Days(#today, #RT);
#Get Quotes and Phone Numbers
open FILE, "c:/Countdown/countdownNumbers.txt" or die "Couldn't open file: $!";
my $numbers = join("", <FILE>);
close FILE;
open FILETWO, "c:/Countdown/Quotes.txt" or die "Couldn't open file: $!";
my $quotes = join("", <FILETWO>);
close FILETWO;
#Create Arrays and Lengths
my #numbersArray = split(/[\n\r\l]+/, $numbers);
my #quotesArray = split(/[\n\r\l]+/, $quotes);
my $length = #numbersArray;
my $QuotesLength = #quotesArray;
#Send Text Message
for(my $i = 0; $i < $length; $i++){
my $g = Google::Voice->new->login('secret', 'secret');
$g->send_sms($numbersArray[$i] => " Countdown\nDays Left: " . $days . "\n Quote:\n" . $quotesArray[0]);
}
#Send Twitter Message
my $nt = Net::Twitter->new(
traits => [qw/OAuth API::REST/],
consumer_key => 'secret',
consumer_secret => 'secret',
access_token => 'secret',
access_token_secret => 'secret'
);
my $result = $nt->update($days .' Days left!');
$result = $nt->update('Quote: ' . $quotesArray[0]);
#Rewrite the file and close it
open FILETWO, ">c:/Countdown/Quotes.txt";
for(my $i = 1; $i < $QuotesLength; $i++){
print FILETWO $quotesArray[$i] . "\n";
}
close FILETWO;
errors
Algorithm\Diff\XS.pm:
error: Can't locate Algorithm\Diff\XS.pm
refby: C:\Perl\site\lib\Array\Diff.pm line 7
Date\Calc\XS.pm:
error: Can't locate Date\Calc\XS.pm
refby: C:\Perl\lib\Date\Calc.pm line 26
I18N\Langinfo.pm:
error: Can't locate I18N\Langinfo.pm
refby: C:\Perl\lib\Encode\Locale.pm line 51
JSON\PP58.pm:
error: Can't locate JSON\PP58.pm
refby: C:\Perl\lib\JSON\PP.pm
Net.pm:
error: Can't locate Net.pm
refby: perlapp --add Net::
Can't locate Mojo/EventEmitter.pm in #INC (#INC contains:) at /<C:\Users\Chris\Desktop\Countdown\RT.exe>Mojo/Base.pm line 32.
BEGIN failed--compilation aborted at /<C:\Users\Chris\Desktop\Countdown\RT.exe>Mojo/UserAgent.pm line 2.
BEGIN failed--compilation aborted at /<C:\Users\Chris\Desktop\RTCountdown\RT.exe>Google/Voice.pm line 6.
BEGIN failed--compilation aborted at RT.pl line 4.
Compiling perl script into exe file is not so straight-forward, I'm afraid. ) Check this discussion at Perlmonks for details.
From what you've quoted it seems that you might start fixing that with installing additional modules: Algorithm::Diff::XS, Date::Calc::XS, etc.
If you use latest version of perlapp, send this error to ActiveState support.
Temporarily you can use PAR::Packer instead of perlapp. Install PAR::Packer with cpan shell (ppm may not work). Then run
pp -c t1.pl
It will create a.out. If it would not work, install Module::ScanDeps from svn: http://svn.openfoundry.org/par/Module-ScanDeps/trunk/ - I fixed a couple of possible problems for your program.
I never used perlapp, but it may have command line switches to provide a list of modules to include.
I have downloaded Langinfo.pm from http://search.cpan.org/src/RJBS/perl-5.16.1/ext/I18N-Langinfo/Langinfo.pm to C:\Perl\lib\I18N and it works.
Komodo IDE, version 6.1.3
Perl Dev Kit Pro v9.1.1.
ActivePerl-5.14.2.1402-MSWin32-x86-295342
I am getting the an error while reading a file and below is the script.
#!/bin/bash
$file = "SampleLogFile.txt"; #--- line 2
open(MYINPUTFILE,$file); #--- line 3
while(<**MYINPUTFILE**>) {
# Good practice to store $_ value because
# subsequent operations may change it.
my($line) = $_;
# Good practice to always strip the trailing
# newline from the line.
chomp($line);
# Convert the line to upper case.
print "$line" if $line = ~ /sent/;
}
close (MYINPUTFILE);
Output :
PerlTesting_New.ksh[2]: =: not found
PerlTesting_New.ksh[3]: syntax error at line 3 : `(' unexpected
Any idea what the issue is ?
Change
#!/bin/bash
to
#!/usr/bin/perl
Otherwise Perl will not be interpreting your script. Change path accordingly as per your system
Okay, whoever is teaching you to write Perl like this needs to move out of the nineties.
#!/usr/bin/perl
use strict; # ALWAYS
use warnings; # Also always.
# When you learn more you can selectively turn off bits of strict and warnings
# functionality on an as needed basis.
use IO::File; # A nice OO module for working with files.
my $file_name = "SampleLogFile.txt"; # note that we have to declare $file now.
my $input_fh = IO::File->new( $file_name, '<' ); # Open the file read-only using IO::File.
# You can avoid assignment through $_ by assigning to a variable, even when you use <$fh>
while( my $line = $input_fh->getline() ) {
# chomp($line); # Chomping is usually a good idea.
# In this case it does nothing but screw up
# your output, so I commented it out.
# This does nothing of the sort:
# Convert the line to upper case.
print "$line" if $line = ~ /sent/;
}
You can also do this with a one liner:
perl -pe '$_ = "" unless /sent/;' SampleLogFile.txt
See perlrun for more info on one-liners.
hmm, your first line : #!/bin/bash
/bin/bash : This is the Bash shell.
You may need to change to
!/usr/bin/perl