Re: https://stackoverflow.com/questions/23937389/determine-parent-shell-from-perl/25139489 - perl

Has anyone tried this code on cygwin?
I get these errors:
Can't find string terminator "'" anywhere before EOF at -e line 1.
Use of uninitialized value in pattern match (m//) at ./dos_it.pl line 506.
Use of uninitialized value $shellpath in rindex at ./dos_it.pl line 586.
Use of uninitialized value $shellpath in substr at ./dos_it.pl line 586.
Use of uninitialized value $pathToShell in concatenation (.) or string at ./dos_it.pl line 761.
Use of uninitialized value $shell_conformance in concatenation (.) or string at ./dos_it.pl line 761.
The string that is generated is:
$ ps -ef | perl -ane '1..1 and /^(.*)CO?MM?A?N?D/ and $s=length $1;s/^.{$s}//; print "#F[1,2] $_"'
Perl version:
$ perl -v
This is perl 5, version 26, subversion 2 (v5.26.2) built for MSWin32-x64-multi-thread

That is a command for the Bourne shell (sh) or similar, but you gave it to the Windows shell (cmd) to execute. Execute the command using sh or similar (whether cygwin-built or otherwise) to get rid of the error.
By the way, you were using a Windows build of Perl (MSWin32-x64 arch), not a cygwin build of Perl (cygwin arch). That's not the cause of the error, as the program will run fine either way. That said, this "issue" will surely go away once you use a cygwin-built sh or similar to execute the command.

Related

Global Replace Email Address With Perl

I try to use Perl to global replace the email address in my shell scripts but it seems Perl can not replace if there is # character.
Part of my shell script:
MAIL_LIST_2="user01#abc.com"
The perl command:
perl -pi -e "s/user01#abc.com/user01#devemail.abc.com/g" test.sh
Any idea?
Escape the # sign in the email addresses in the Perl code:
echo 'MAIL_LIST_2="user01#abc.com"' |
perl -p -e "s/user01\#abc.com/user01\#devemail.abc.com/g"
which gives the output:
MAIL_LIST_2="user01#devemail.abc.com"
The problem is that Perl regards an unescaped # as the sigil for an array, and tries to interpolate the content of the (non-existent) arrays into the regex, which doesn't work as you want it to.
Note that if you enabled warnings — -w on the command line, or use strict; use warnings; in a script file — then you get told why things are not working so well:
echo 'MAIL_LIST_2="user01#abc.com"' |
perl -pwe "s/user01#abc.com/user01#devemail.abc.com/g"
Possible unintended interpolation of #abc in string at -e line 1.
Possible unintended interpolation of #devemail in string at -e line 1.
Name "main::abc" used only once: possible typo at -e line 1.
Name "main::devemail" used only once: possible typo at -e line 1.
MAIL_LIST_2="user01#abc.com"
Moral: always enable warnings in Perl scripts — it avoids unnecessary pain.
I just ran into this problem.
Possible unintended interpolation of #example in string at ./test/capture.pl line 20.
Possible unintended interpolation of #host in string at ./test/capture.pl line 20.
Global symbol "#example" requires explicit package name (did you forget to declare "my #example"?) at ./test/capture.pl line 20.
Global symbol "#host" requires explicit package name (did you forget to declare "my #host"?) at ./test/capture.pl line 20.
Solution is of course quoting, and I found the answer after a lot of googling.
$line5 is the one giving the line 20 error.
$line4 has the answer. The q() does single-quotes
my ($line4) =
q(Message 1A2D2V0L007336 from [20.85.223.71] <> to <user#example.com> with subject 'Postmaster notify: see transcript for details' message-id '<202111021302.1A2D2kq3001573#host.example.com>' date 'Tue, 2 Nov 2021 14:02:46 +0100' infected by {HEX}EICAR.TEST.3.UNOFFICIAL);
my ($line5) =
"Message 1A2D2V0L007336 from [20.85.223.71] <> to <user#example.com> with subject 'Postmaster notify: see transcript for details' message-id '<202111021302.1A2D2kq3001573#host.example.com>' date 'Tue, 2 Nov 2021 14:02:46 +0100' infected by {HEX}EICAR.TEST.3.UNOFFICIAL";
Reference: Strings in Perl: quoted, interpolated and escaped

perl hash syntax error on command line

When I tried hash in command line as in the below example, I am getting syntax error. I tried using fat comma as well but still the same result. Can someone help me?
perl -e "%hash_ex=(as,wdesadc,afcsdc,esvdfvzdfvfv,1,sd,34,34);print $hash_ex{'1'};"
syntax error at -e line 1, near "};"
Execution of -e aborted due to compilation errors.
perl -e "%hash_ex=('a' => 1 , 'b' => 2);print $hash_ex {a};"
syntax error at -e line 1, near "};"
Execution of -e aborted due to compilation errors.
the problem is that your Shell also substitutes variables beginning with $:
# (on zsh and bash)
echo "%hash_ex=(as,wdesadc,afcsdc,esvdfvzdfvfv,1,sd,34,34);print $hash_ex{'1'};"
%hash_ex=(as,wdesadc,afcsdc,esvdfvzdfvfv,1,sd,34,34);print {'1'};
Because of this, you'll better use single qotes for your -E argument:
perl -e'%hash_ex=(as,wdesadc,afcsdc,esvdfvzdfvfv,1,sd,34,34);print $hash_ex{1};'
sd
if you really need single quotes (in this case you don't), you can use the q operator:
perl -E'say q~some non-interpolating string\t\n$_~'
some non-interpolating string\t\n$_
Or you can try to avoid the interpolating of your shell:
perl -e "%hash_ex=(as,wdesadc,afcsdc,esvdfvzdfvfv,1,sd,34,34);print \$hash_ex{'1'};"
You are using double quotes to pass your command to Perl. This will mean that the shell will first interpolate any variables in your string before it then passes the command to Perl. you can see this if you just run echo on the string with double quotes then single quotes. The output from echo will show what the shell is then passing to Perl
When the shell processes the text in the double quotes it interpolates the $hash_ex. Since this is not set in the shell this gets interpolated as nothing which means your print statement instead of being
print $hash_ex{a}
becomes
print {a}
So you need to wrap all your perl in singleqotes so that the shell does not interpolate any vars and passes the full string to perl as literal string.

strange error message in a complex, but legal Perl one-liner

>perl -e '$_ = q(t b[\)sizeof];); s/(t?(\w)(?:\s(\w))?\s(\w)(\[([^\]]+)\]))/eval $1/e'
Bareword found where operator expected at (eval 1) line 1, near ")sizeof"
(Missing operator before sizeof?)
This is legal Perl, then why the error message? I have the latest Perl.
This is an SSCCE ; any one character less and the error message does not appear.
The Perl code is valid, but you are trying to eval a string which is not valid Perl code. When I run this code and swap eval for print, it prints the string:
t b[)sizeof]
Now if I try and run this as Perl code I get:
> perl -we't b[)sizeof]'
Bareword found where operator expected at -e line 1, near ")sizeof"
(Missing operator before sizeof?)
Unquoted string "sizeof" may clash with future reserved word at -e line 1.
syntax error at -e line 1, near "[)"
Execution of -e aborted due to compilation errors.
(You should always use warnings -w, even with one-liners)
This code does exactly what your evaluation is trying to do: It's trying to run that string as Perl code, and it fails because that string is not valid Perl code.
Also you should be careful when using eval, as it can do unexpected and catastrophical things to your computer. Usually, this kind of double evaluation is written using two of the /e modifiers, e.g.:
s/.../.../ee
Which is a bit more convenient than
s/.../eval .../e

How to write perl one liner in Make?

I am writing the following command to extract the text in makefile:-
#awk '/Exported Layer/,/Total Polygons/' out_compare.err | perl -lane '$el=$F[3] if(/Exported Layer/); print "$el: $f[3]" if (/Total Polygons/);' | cat
But it is giving the following error:-
Can't modify constant item in scalar assignment at -e line 1, near "] if"
Execution of -e aborted due to compilation errors.
Would you guys like to suggest something? :-)
Make is oblivious to shell quoting in commands, so the $ characters in your Perl snippet are being interpreted as make variables $e and $F. These variables don't exist in your makefile and are being expanded as empty, leading to the Perl syntax errors you're seeing.
You need to escape the $ characters from make like this:
... perl -lane '$$el=$$F[3] if(/Exported Layer/); ...
See also the GNU Make manual.

How do I get the Perl's DateTime::Format::DateManip version number from the command line?

I'm using this from the command line:
perl -MDateTime::Format::DateManip -le 'print $Some::Module::VERSION'
but only return a blank line, any thoughts?
It is pseudo-code, Some isn't set so it is just printing out undef with the -l flag, like perl -le'print undef;
For evidence turn on warnings with -w
$ perl -MDateTime::Format::DateManip -wle 'print $Some::Module::VERSION'
Use of uninitialized value $Some::Module::VERSION in print at -e line 1.
Substitute Some::Module with the module you want the version of.
Also, just for fun ;)
Perl Shorthands for testing version numbers
These are quick ways to get version numbers by utilizing the use <module> <version> syntax and perl's vocal rejection of versions that aren't new enough.
These are all equivalent of creating a perl script with use DateTime 9999;
$ perl -MDateTime\ 9999
DateTime version 9999 required--this is only version 0.51.
BEGIN failed--compilation aborted.
However, this fashion isn't cross-platform, because you're simply telling bash to escape a space. This doesn't work in windows cmd, for that you'll have to
$ perl -M"DateTime 9999"
DateTime version 9999 required--this is only version 0.51.
BEGIN failed--compilation aborted.
Here, you just put it in quotes - that tells cmd to send it all as an argument to perl and it gets the same job done.
If you find yourself doing this frequently, you can download and install pmvers from CPAN. The script will save you from typing a potentially lengthy module name twice:
pmvers DateTime::Format::DateManip