Perl Compiling PP issue in Strawberry Perl [duplicate] - perl

I've been using pp
https://metacpan.org/pod/pp
A while ago!
However when hiring another hosting, when I run the pp command the scripts do not run on the server
CentOS Linux release 7.9.2009 (Core)
Perl v 5.32.1
Command using pp, host old
$ pp -x -c name.pl
When running
./a.out
Unable to open html entities file (/tmp/par-726f6f74/cache-78cdefedff4d2afddea0035addc3b570c8f0bfd5/inc/lib/Mojo/resources/html_entities.txt): No such file or directory at script / name.pl line 13.
Compilation failed in require at script / name.pl line 13.
BEGIN failed - compilation aborted at script / name.pl line 13.
And when I run ./name.pl it runs normally.
Any suggestion?
name.pl
#!/usr/bin/perl
use FindBin qw($Bin);
use lib ("$Bin");
use DBI;
use Number::Format;
use Encode qw(decode encode);
use File::Basename;
use Mojo::Util qw(b64_encode b64_decode url_escape url_unescape);
use Mojo::JSON qw(decode_json encode_json);
use Image::ExifTool;
use LWP;
print "Test Mojo";
This same command works normally in version 5.28 on another server/hosting

You need to add the file html_entities.txt to the archive.
The following seems to work for me:
Find the location of the file:
$ perl -MMojo::Util -MFile::Basename=dirname -E '$fn = (dirname $INC{"Mojo/Util.pm"}) . "/resources/html_entities.txt"; say $fn'
/home/hakon/perlbrew/perls/perl-5.32.0/lib/site_perl/5.32.0/Mojo/resources/html_entities.txt
Copy the file to a local directory:
$ mkdir -p ./lib/Mojo/resources/
$ cp /home/hakon/perlbrew/perls/perl-5.32.0/lib/site_perl/5.32.0/Mojo/resources/html_entities.txt ./lib/Mojo/resources/
Add the file to the archive
$ pp -x -c -a lib/Mojo/resources/html_entities.txt name.pl

Related

How can I use rperl with perlbrew?

I have this simple rperl program:
#!/usr/bin/env perl
use RPerl;
use strict;
use warnings;
our $VERSION = 0.001_000;
# [[[ CRITICS ]]]
## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator
## no critic qw(RequireInterpolationOfMetachars) # USER DEFAULT 2: allow single-quoted control characters & sigils
## no critic qw(ProhibitInterpolationOfLiterals) # USER DEFAULT 3: allow anything
print 'Hello Perl', "\n";
See Exercise 1 in Learning RPerl. I am on Ubuntu 19.04, using perlbrew with perl version 5.28.1. I installed RPerl using:
$ cpanm RPerl
Then I tried to compile the above program:
$ rperl -D p.pl
[...]
[[[ SUBCOMPILE STDERR ]]]
/bin/ld: cannot find -lperl
collect2: error: ld returned 1 exit status
ERROR ECOCOSU04, COMPILER, SUBCOMPILE: C++ compiler returned error code,
[...]
Apparently, rperl needs to link against libperl.so, but the perl I installed rperl with was not built with a shared library libperl.so. The solution was to install a new perl using configure option -Duseshrplib:
$ perlbrew install perl-5.30.0 --notest --noman --as=5.30.0-reloc -Duseshrplib
$ perbrew use 5.30.0-reloc
$ cpanm RPerl
$ rperl -V p.pl
[...]
$ ./p
Hello Perl

Conditional Perl Shebang?

I have a situation where I need to detect if a particular perl executable, /usr/goofy/bin/perl exists and if so use it to run the Perl script otherwise use /usr/bin/perl.
I have been struggling with this small POC script, called perlshebang.pl:
#!/bin/sh -e
perls="/usr/goofy/bin/perl /usr/bin/perl"
for pl_exec in $perls
do
if [ -x $pl_exec ]; then
exec "$pl_exec -w -S \"$0\" ${1+\"$#\"}"
fi
done
print "[$^X] Whoop!\n";
When I run this on a system that does not have /usr/goofy/bin/perl I get this error message:
./perlshebang.pl: 6: exec: /usr/bin/perl -w -S "./perlshebang.pl" : not found
And when I run it on a system that does have /usr/goofy/bin/perl I get a similuar error message:
./perlshebang.pl: line 6: /usr/goofy/bin/perl -w -S "./perlshebang.pl" : No such file or directory
I think I am close but cannot figure out why I am getting these error messages.
Thanks!
To answer your question, "Why am I getting these error messages?", the problem is your exec line:
exec "/path/to/cmd arg arg"
# This will attempt to execute a file named "cmd arg arg"
# (with spaces in name) in directory /path/to/
Contrast that with
exec /path/to/cmd arg arg
# This will attempt to execute a file named "cmd" in directory
# /path/to/, with arguments "arg" and "arg"
So, that is why the shell complains that it cannot find your executable. You don't have a file named perl -w -s "perlshebang.pl", neither under /usr/bin/ nor under /usr/goofy/bin/.
This sounds a little ugly to me if you are releasing software that uses this hack
If you have no other choice, then I suggest you make sure there is always a /usr/goofy/bin/perl, and use the shebang line
#!/usr/goofy/bin/perl
on all your scripts.
For those systems where you want to use the system perl, just make /usr/goofy/bin/perl a symlink to /usr/bin/perl
A co-worker of mine came up with this. I am not sure I fully understand it but it seems to work fine:
#!/bin/sh
#! -*-perl-*-
eval ' if test -x /usr/goofy/bin/perl ; then
exec /usr/goofy/bin/perl -x -S $0 ${1+"$#"};
elif test -x /usr/bin/perl ; then
exec /usr/bin/perl -x -S $0 ${1+"$#"};
fi '
if $running_under_some_shell;
use strict;
use warnings;
print "hello world\n"; # if $foo;
printf("running %s v(%vd)\n", $^X, $^V);
__END__
unpod like docs.
See http://perldoc.perl.org/perlrun.html
You can run the idea out of a Perl script running /usr/bin/perl. Use the shebang line with the 'goofy perl' in your script that should run. Then run the following wrapper, followed by the normal invocation of the script (its name and arguments).
#!/usr/bin/perl
exec "#ARGV";
exec "/usr/bin/perl #ARGV";
print STDERR "Couldn't execute either.\n";
Let's call the above pick_perl.pl, and your script is script.pl. Run it all as
pick_perl.pl script.pl args-for-script
The exec replaces the running program altogether with the one it executes, ie. it loads the new program. Thus your script runs with its own shebang. If that failes exec returns quietly (with false) and the next statement is executed so the other Perl runs the script (overriding the shebang). This happens if script's shebang fails, but also if the first exec fails to execute for any reason.
If you wish/need to run checks then put exec in a full if block. One can also interrogate the 'goofy_perl' file further if -e isn't assuring enough.
#!/usr/bin/perl
$system_perl = "/usr/bin/perl";
$goofy_perl = "/usr/goofy/bin/perl";
# Your 'goofy_perl' script with its arguments
#script_cmd = #ARGV;
if (-x $goofy_perl) { exec "#script_cmd" }
exec "$system_perl #script_cmd";
The #script_cmd has the full command line for your script (which has 'goofy_perl' shebang).

Error: Can't locate File/HomeDir.pm in #INC

I use a Mac OS X 10.8, and want to run the latexindent.pl perl script on my latex files. This script is made by https://github.com/cmhughes/latexindent.plx. When I run this script on a latexfile I get this error message:
Can't locate File/HomeDir.pm in #INC (#INC contains: /Library/Perl/5.12/darwin-thread-multi-2level /Library/Perl/5.12 /Network/Library/Perl/5.12/darwin-thread-multi-2level /Network/Library/Perl/5.12 /Library/Perl/Updates/5.12.4/darwin-thread-multi-2level /Library/Perl/Updates/5.12.4 /System/Library/Perl/5.12/darwin-thread-multi-2level /System/Library/Perl/5.12 /System/Library/Perl/Extras/5.12/darwin-thread-multi-2level /System/Library/Perl/Extras/5.12 .) at helloworld.pl line 10.
BEGIN failed--compilation aborted at helloworld.pl line 10.
It seems that I am missing the File::HomeDir module in perl so I tried to download it using:
sudo perl -MCPAN -e 'install File::HomeDir',
I get the following error:
Can't locate object method "install" via package "File::HomeDir".
I managed to install the YAML::Tiny package without any problems.
I tried to run:
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5 use FindBin;
6 use YAML::Tiny;
7 use File::Copy;
8 use File::Basename;
9 use Getopt::Std;
10 use File::HomeDir;
11
12 print "hello world";
13 exit;
and got the same Error message as above...
Do anyone know what to do?
sudo perl -MCPAN -e 'install "File::HomeDir"'
^ ^
I had a similar problem. I just ran these commends, and it worked for me
sudo cpan -i File::HomeDir
then
sudo cpan -i Unicode::GCString
Basically, I will run latexindent file_name.tex, then an error message will appear that says you may need to install the XXXX module then I install the XXXX module using sudo cpan -i XXXX

Why does Perl not want to require certain files when running under -T?

I recently noticed that on my system it is not possible to require 'lib/file.pl' when running under -T, but require './lib/file.pl' works.
$ perl -wT -e 'require "lib/file.pl";'
Can't locate lib/file.pl in #INC (#INC contains: /usr/lib/perl5/site_perl/5.14.2/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.14.2 /usr/lib/perl5/vendor_perl/5.14.2/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.14.2 /usr/lib/perl5/5.14.2/x86_64-linux-thread-multi /usr/lib/perl5/5.14.2 /usr/lib/perl5/site_perl/5.14.2/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.14.2 /usr/lib/perl5/site_perl)
$ perl -wT -e 'require "lib/file.pl"'
Doing it without -T works in both ways:
$ perl -w -e 'require "lib/file.pl"'
$ perl -w -e 'require "./lib/file.pl"'
In taint mode, . is not part of #INC.
perl -w -e 'print "#INC"'
[..snip..] /usr/lib/perl5/site_perl/5.14.2 /usr/lib/perl5/site_perl .
perl -wT -e 'print "#INC"'
[..snip..] /usr/lib/perl5/site_perl/5.14.2 /usr/lib/perl5/site_perl
I could not find that behavior in the doc. Can someone please tell me where this is documented or why -T doesn't like . as a lib directory?
Erm... this is actually well documented, I suppose:
When the taint mode (-T ) is in effect, the "." directory is removed
from #INC , and the environment variables PERL5LIB and PERLLIB are
ignored by Perl. You can still adjust #INC from outside the program by
using the -I command line option as explained in perlrun.
... but that's only a half on an answer, I suppose. The reasons behind such decision are given here:
... the issue with #INC is really more of a problem with SUID scripts
than CGI scripts. When you have an SUID script that can execute with
the permissions of another user (such as root), Perl goes into
taintmode automatically.
For this SUID script case, it would be a huge security breach to have
the capability of loading libraries from the user's current directory.
If a script ends up having a bug where the library is not found in the
normal directory path, then a user could exploit this by writing their
own, malicious version of the library, putting it in the current
directory, and running the SUID script from their current directory.
However, this is not really the same problem with CGI scripts. User's
are not executing your script from arbitrary directories. Your web
server controls which directory the script is called from. So keeping
"." in #INC is not really a problem compared to SUID scripts which
operate under taint mode automatically.

Cannot execute system command in cygwin

I have the following simple perl script that I cannot execute in cygwin:
#!/usr/bin/perl
use strict;
system("../cat.exe < a.txt > b.txt");
When I run it, the script tells me:
./my_test.pl
'..' is not recognized as an internal or external command,
operable program or batch file.
However I can run the command in the cygwin shell:
$ ../cat.exe < a.txt > b.txt
$ ../cat.exe b.txt
hello
The executable cat.exe exists in the directory above and a.txt in the current working
directory.
My version of perl:
$ perl -v
This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 12 registered patches, see perl -V for more detail)
You're using a perl built for Windows (ActiveState? Strawberry?), not the Cygwin version. It invokes cmd.exe for system(), which thinks that .. is the command and / introduces an option.
Try changing the the system() call to:
system("..\\cat.exe < a.txt > b.txt");
But you should normally be using the Cygwin version of perl when running a script from bash.
What is the output of the following commands?
echo "$PATH"
type -a perl
/usr/bin/perl -v
From what we've seen so far, it looks like you've installed some Windows-specific Perl with its perl.exe in your Cygwin /usr/bin directory. If so, then (a) uninstall it (you can reinstall it elsewhere if you like), and (b) re-install the "perl" package via Cygwin's setup.exe.
(And add use warnings; after use strict; in your Perl scripts. This isn't related to your problem, but it's good practice.)
The error message obviously comes from cmd.exe, which apparently is your default shell. What does echo $SHELL say? Maybe you need to define that variable to become /bin/bash.exe.