I am getting a lot of Global symbol <symbol> requires explicit package name errors in my code, immediately after the line of code where I have used smart matching. All of those global variables are defined and code worked before using smart matching.
if (ref($aActivityErrorStrings) eq "ARRAY" && $sChompedOutput ~~ #$aActivityErrorStrings)
The first line of error gives me a hint that there is something wrong with my usage of smart matching. Error line is
Status message: Failed: syntax error at common.pm line 320, near "$sChompedOutput ~" Global symbol "$rOutput" requires explicit package name
my Perl version is 5.12
Can someone please tell me what is wrong with smart matching?
My mistake guys. User of this code was running it on a device which had Perl version 5.8.
Thank you for all the feedbacks. Much appriciated.
Error here:
if (ref($aActivityErrorStrings) eq "ARRAY"
&& $sChompedOutput ~~ #$aActivityErrorStrings))
^
|
You've got an extra closing parenthesis. Here's proof that your code can work:
use strict;
use warnings;
use 5.020;
my $aActivityErrorStrings = [
"Error1",
"Error2",
];
my $sChompedOutput = "Error1";
if (ref($aActivityErrorStrings) eq "ARRAY"
&& $sChompedOutput ~~ #$aActivityErrorStrings) {
say 'yes'
}
say "#$aActivityErrorStrings";
--output:--
Smartmatch is experimental at 1.pl line 14.
yes
Error1 Error2
The error
Global symbol "$sChompedOutput" requires explicit package name at ...
pops up, if you have $sChompedOutput undefined.
The following code produces this error:
my $aActivityErrorStrings = ["mumu", "Bubu", "hello"];
#my $sChompedOutput = "hello";
if (ref($aActivityErrorStrings) eq "ARRAY" && $sChompedOutput ~~ #$aActivityErrorStrings) {
print "have hello";
}
if you remove the comment before #my $sChomped... the error goes away.
Related
I am using the # operator, and while with one casting it works fine, having two in the same rule it does not compile. The sentence is the following
configuration#RuleSetConfiguration.configurationRule[0].configurationRuleAction#FilteringAction.filteringActionType==$mspl1.configuration#RuleSetConfiguration.configurationRule[0].configurationRuleAction#FilteringAction
And it returns the following compilation error:
[ERR 102] Line 62:87 mismatched input '#' in rule "verify_same_filtering_l4_behaviour" [Message [id=1, kieBase=rules, level=ERROR, path=/home/santiago/eclipse-workspace/DroolKieServer/target/classes/com/sample/rules/Rule.drl, line=62, column=0 text=[ERR 102] Line 62:87 mismatched input '#' in rule "verify_same_filtering_l4_behaviour"], Message [id=2, kieBase=rules, level=ERROR, path=/home/santiago/eclipse-workspace/DroolKieServer/target/classes/com/sample/rules/Rule.drl, line=0, column=0 text=Parser returned a null Package]]
I have tried to use brackets but the result is the same. Is there a limitation on the castings that can be done over a rule?
Greetings
I tried to do two castings in the rule. The expected result is to compile fine due to the use of the # operator is correct, but it returns the compilation error
`
[Message [id=1, kieBase=rules, level=ERROR, path=/home/santiago/eclipse-workspace/DroolKieServer/target/classes/com/sample/rules/Rule.drl, line=62, column=0
text=[ERR 102] Line 62:87 mismatched input '#' in rule "verify_same_filtering_l4_behaviour"], Message [id=2, kieBase=rules, level=ERROR, path=/home/santiago/eclipse-workspace/DroolKieServer/target/classes/com/sample/rules/Rule.drl, line=0, column=0
text=Parser returned a null Package]]
`
The problem was about using the # operator after a list. Instead of that, the standard Java casting have being used and it works fine:
((FilteringAction)((RuleSetConfiguration)configuration).configurationRule[0].configurationRuleAction)
I am trying to remove the old files in a dir if the count is more than 3 over SSH
Kindly suggest how to resolve the issue.
Please refer the code snippet
#!/usr/bin/perl
use strict;
use warnings;
my $HOME="/opt/app/latest";
my $LIBS="${HOME}/libs";
my $LIBS_BACKUP_DIR="${HOME}/libs_backups";
my $a;
my $b;
my $c;
my $d;
my $command =qq(sudo /bin/su - jenkins -c "ssh username\#server 'my $a=ls ${LIBS_BACKUP_DIR} | wc -l;my $b=`$a`;if ($b > 3); { print " Found More than 3 back up files , removing older files..";my $c=ls -tr ${LIBS_BACKUP_DIR} | head -1;my $d=`$c`;print "Old file name $d";}else { print "No of back up files are less then 3 .";} '");
print "$command\n";
system($command);
output:
sudo /bin/su - jenkins -c "ssh username#server 'my ; =ls /opt/app/latest/libs_backups | wc -l;my ; =``;if ( > 3); { print " Found More than 3 back up files , removing older files..";my ; =ls -tr /opt/app/latest/libs_backups | head -1;my ; =``;print "Old file name ";}else { print "No of back up files are less then 3 .";} '"
Found: -c: line 0: unexpected EOF while looking for matching `''
Found: -c: line 1: syntax error: unexpected end of file
If you have three levels of escaping, you're bound to get it wrong if you do it manually. Use String::ShellQuote's shell_quote instead.
Furthermore, avoid generating code. You're bound to get it wrong! Pass the necessary information using arguments, the environment or some other channel of communication instead.
There were numerous errors in the interior Perl script on top of the fact that you tried to execute a Perl script without actually invoking perl!
#!/usr/bin/perl
use strict;
use warnings;
use String::ShellQuote qw( shell_quote );
my $HOME = "/opt/app/latest";
my $LIBS = "$HOME/libs";
my $LIBS_BACKUP_DIR = "$HOME/libs_backups";
my $perl_script = <<'__EOI__';
use strict;
use warnings;
use String::ShellQuote qw( shell_quote );
my ($LIBS_BACKUP_DIR) = #ARGV;
my $cmd = shell_quote("ls", "-tr", "--", $LIBS_BACKUP_DIR);
chomp( my #files = `$cmd` );
if (#files > 3) {
print "Found more than 3 back up files. Removing older files...\n";
print "$_\n" for #files;
} else {
print "Found three or fewer backup files.\n";
}
__EOI__
my $remote_cmd = shell_quote("perl", "-e", $perl_script, "--", $LIBS_BACKUP_DIR);
my $ssh_cmd = shell_quote("ssh", 'username#server', "--", $remote_cmd);
my $local_cmd = shell_quote("sudo", "su", "-c", $ssh_ccmd);
system($local_cmd);
I created a new file and handling the dir check and deletion logic , scp file to remote server and executing in remote server , after completion removing the file.
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use File::Path;
use FindBin;
use File::Copy;
my $HOME="/opt/app/test/latest";
my $LIBS_BACKUP_DIR="${HOME}/libs_backups";
my $a="ls ${LIBS_BACKUP_DIR} | wc -l";
my $b=`$a`;
my $c="ls -tr ${LIBS_BACKUP_DIR} | head -1";
my $d=`$c`;
chomp($d);
print " count : $b\n";
if ($b > 3)
{
print " Found More than 3 back up files , removing older files..\n";
print "Old file name $d\n";
my $filepath="${LIBS_BACKUP_DIR}/$d";
rmtree $filepath;
}
else
{
print "No of back up files are less then 3 .\n";
}
I need to write a perl program where I parse through an error log and output the error messages to a new file. I am having issues with setting up the regex to do this. In the error log, an error code starts with the word "ERROR" and the end of each error message ends with a ". " (period and then a space). I want to find all the errors, count them, and also output the entire error message of each error message to a new file.
I tried this but am having issues:
open(FH,"<$filetoparse");
$outputfile='./errorlog.txt';
open(OUTPUT,">$outputfile");
$errorstart='ERROR';
$errorend=". ";
while(<FH>)
{
if (FH=~ /^\s*$errorstart/../$errorend/)
{
print OUTPUT "success";
}
else
{
print OUTPUT "failed";
}
}
}
the $errorstart and $errorend are something I saw online and am not sure if that is the correct way to code it.
Also I know the printing "Success" or "Failure" is not what I said I am looking for, I added that in to help with confirmed that the code works, I haven't tried coding for counting the error messages yet.
before this snippet of code I have a print statement asking the user for the location address of the .txt file they want to parse. I confirmed that particular section of code words properly. Thanks for any help! Let me know if more info is needed!
Here is an example of data that I will be using:
Sample Data
-----BEGIN LOAD-----
SUCCESS: file loaded properly .
SUCCESS: file loaded properly .
SUCCESS: file loaded properly .
SUCCESS: file loaded properly .
SUCCESS: file loaded properly .
SUCCESS: file loaded properly .
ERROR: the file was unable to load for an unknown reason .
SUCCESS: file loaded properly .
SUCCESS: file loaded properly .
ERROR: the file was unable to load this is just an example of a log file that will span
multiple lines .
SUCCESS: file loaded properly .
------END LOAD-------
While the log may not necessarily NEED to span multiple lines, there will be some data throughout the log that will similar to how it is above. Every message logged starts with either SUCCESS or ERROR and the message is done when a " . " (whitespace-period-whitespace) is encountered. The log I want to parse through is 50,000 entries long so needless to say I would like to code so it will also identify multi-line error msgs as well as output the entire multi-line message to the output file.
update
I have written the code but for some reason it won't work. I think it has to do with the delimiter but I can't figure out what it is. The file I am using has messages that are separated by "whitespace period newline". Can you see what I'm doing wrong??
{
local $/ = " .\n";
if ($outputtype == 1)
{
$outputfile="errorlog.txt";
open(OUTPUT,">>$outputfile");
$errorcount=0;
$errortarget="ERROR";
print OUTPUT "-----------Error Log-----------\n";
{
while(<FH>)
{
if ($_ =~ m/^$errortarget/)
{
print OUTPUT "$_\n";
print OUTPUT "next code is: \n";
$errorcount++;
}
}
print OUTPUT "\nError Count : $errorcount\n";
}
}
}
There are several problems with your code to start off.
ALWAYS use strict; and use warnings;.
3 argument open is much less error prone. open ( my $fh, "<", $filename ) or die $!;
Always check open actually worked.
FH =~ doesn't do what you think it does.
range operator tests if you're between two chunks of text in code. This is particularly relevant for multi-line operations. If your error log isn't, then it's not what you need.
Assuming you've error data like this:
ERROR: something is broken.
WARNING: something might be broken.
INFO: not broken.
ERROR: still broken.
This code will do the trick:
use strict;
use warnings;
my $filetoparse = "myfile.txt";
my $outputfile = "errorlog.txt";
open( my $input, "<", $filetoparse ) or die $!;
open( my $output, ">", $outputfile ) or die $!;
my $count_of_errors = 0;
#set record delimiter
local $/ = " . \n";
while ( my $lines = <$input> ) {
$lines =~ s/^-----\w+ LOAD-----\n//g; #discard any 'being/end load' lines.
if ( $lines =~ m/^ERROR/ ) {
$count_of_errors++;
print {$output} $lines;
}
}
close ( $input );
close ( $output );
print "$count_of_errors errors found\n";
If you've multi-line error message, then you'll need a slightly different approach though.
I was searching the web for help and didn't find any. Thats why I thought it might be a good idea to document my problem here.
I had the following problem while documenting a really old (15-20 years) FORTRAN-Code with doxygen. I have a file with the same filename as the subroutine in it. And some of these files gave me an error:
********************************************************************
Error in file FILENAME line: XX, state: 21
********************************************************************
I didn't figure out, what the error state 21 is. After some digging into the code I did find the problem. I have a WRITE-command like
WRITE(*,'('' THIS IS SOME TEXT ''
+ '' THIS IS SOME MORE TEXT : '',I6,
+ /'' AND EVEN MORE TEXT ! '')')
+ VARIABLE
The problem here is the exclamation mark (!) in the code line. Doxygen seems to interpret the end of the line after the exclamation mark as doxygen syntax and not FORTRAN code. I changed the line into
WRITE(*,'('' THIS IS SOME TEXT ''
+ '' THIS IS SOME MORE TEXT : '',I6,
+ /'' AND EVEN MORE TEXT ! ''
+ )')VARIABLE
and now everything works fine!
a simple question:
I want to move emails with a certain subject to a folder and mark them as read afterwards. Moving works for me with
:0: H
* ^Subject:.*(ThisIsMySubject)
$HOME/mail/ThisIsMyFolder
But how to mark the mails as read?
Note: Updated dec. 16th 2011
Procmail solution
The following recipe works for me. .Junk is the spam folder:
MAILDIR=$HOME/Maildir
:0
* ^X-Spam-Flag: YES
{
# First deliver to maildir so LASTFOLDER gets set
:0 c
.Junk
# Manipulate the filename
:0 ai
* LASTFOLDER ?? ()\/[^/]+^^
|mv "$LASTFOLDER" "$MAILDIR/.Junk/cur/$MATCH:2,S"
}
Maildrop solution
Preface: Recently I had (no, I wanted) to do the same thing with a maildropfilter. After reading man maildropfilter I concocted the following recipe. I'm sure people will find this handy - I know I do.
The example below marks new emails as read but also unread old messages.
SPAMDIRFULL="$DEFAULT/.Junk"
if ( /^X-Spam-Flag: YES$/ || \
/^X-Spam-Level: \*\*\*/ || \
/^Subject: \*+SPAM\*/ )
{
exception {
cc "$SPAMDIRFULL"
`for x in ${SPAMDIRFULL}/new/*; do [ -f $x ] && mv $x ${SPAMDIRFULL}/cur/${x##*/}:2,S; done`
`for x in ${SPAMDIRFULL}/cur/*:2,; do [ -f $x ] && mv $x ${SPAMDIRFULL}/cur/${x##*/}S; done`
to "/dev/null"
}
}
Note that the exception command might read counterintuitive. The manual states the following:
The exception statement traps errors that would normally cause
maildrop to terminate. If a fatal error is encountered anywhere within
the block of statements enclosed by the exception clause, execution
will resume immediately following the exception clause.