A perl command line that prints the perl version it is using to run your script - perl

I'd like to know if someone knows a function or command that I can put at the beginning of my Perl script that tells the user for example "this script is being run by perl v 5.XXX".
Specially when we have many versions installed.

$^V shows the "...revision, version, and subversion of the Perl interpreter." From perlvar.

You can use a special variable $]:
$ perl -e 'print $];'
5.014002

Related

How to execute perl file from shell script

I have a question about how to execute the perl file inside of a shell script
I have 2 files now, "test.sh" and "test.pl", here are example of my scripts
SHELL script
#!/bin/bash
perl FILEPATH/test.pl
......
PERL script
#!/usr/bin/perl
my $a = "hello"
sub saysomething
{
print $a;
}
.....
The way I call the shell script is : under the path of shell scripts, execute "./test.sh"
All mentioned above are working under the environment
GUN bash, version 4.2.24(1)-release (i686-pc-linux-gnu) + perl (v5.14.2)
But if I put those scripts on server (which I couldn't change the bash / perl version)
GNU bash, version 4.2.10(1)-release (x86_64-pc-linux-gnu) + perl (v5.12.4), I got the followign message:
FILEPATH/test.pl: line 2: my: command not found
Does anybody know how can I solve this problem?
BTW, if I execute the perl script individually (perl FILEPATH/FILENAME.pl), it works perfectly.
In order to execute a perl script by .sh script you dont need to use perl prefix, but only:
#!/bin/sh
/somewhere/perlScript.pl
It will work without problem.
This problem is at least two-fold. One, you have to have the location of Perl in your environment PATH. Two, the location of Perl may be different on different machines. One solution to both problems that I, and others, have used for years is to make use of a "magic header" of some sort at the top of Perl programs. The header identifies itself as a sh shell script and leverages the fact that /bin/sh exists in every version/flavor of Linux/UNIX. The header's job is to fortify the PATH with various possible Perl locations and then run the Perl script in place of itself (via exec). Here is a "Hello World" example:
1 #! /bin/sh --
2 eval '(exit $?0)' && eval 'PERL_BADLANG=x;PATH="/usr/bin:/bin:/usr/local/bin:$PATH";export PERL_BADLANG;: \
3 ;exec perl -x -S -- "$0" ${1+"$#"};#'if 0;
4 exec 'setenv PERL_BADLANG x;exec perl -x -S -- "$0" $argv:q;#'.q
5 #!/bin/perl -w
6 +($0=~/(.*)/s);do(index($1,"/")<0?"./$1":$1);die$#if$#;__END__+if 0;
7 # Above is magic header ... real Perl code begins here
8 use strict;
9 use warnings;
10 print "hello world!\n";
Note: I added line numbers just to make it clear where lines start and end.
First check where perl is installed on your system, e.g. which perl and use that location in the shebang line instead of /usr/bin/perl, if it is different.
If all other recommendations fail, check the first line of the script on the machine where it is not running properly by doing this: head -1 test.pl | xxd. Does the output show the last two bytes as 0d 0a? If so, you probably copied over the file via Windows and didn't do a dos2unix conversion.
"command not found" is an error emitted by the shell. You are trying to run your Perl script by the shell, not by Perl.

from cron running a subroutine from a perl module

I have a Perl Module that i created and i want to run one of the subroutine in it on a schedule. I know I can just make a small perl script that calls the subroutine and call it from the crontab but if there is a way to call the subroutine right from the crontab that would be cool!
Is this possible?
You can use Perl's -e switch for executing code from the command line, e.g.
perl -e 'use your_module; your_function()'
Make that even shorter with the -M switch for loading a module:
perl -Myour_module -e 'your_function()'
The perlrun man page is your friend.
You can run the subroutine from the command line using something like
perl -MYour::Module=some,functions,to,import,such,as,foo -e 'foo();'
So you will be able to do the same from the crontab. Note that the cron usually runs with a restricted set of environment variables, so you may need to add a -I/path/to/your/modules option.
If you want a more elegant solution, your module can be configured to detect that it is being run as a script and behave differently in that situation. See this discussion: In Perl, how can I find out if my file is being used as a module or run as a script?

Executing perl code inside shell script using eval

I came across the following example. I tried to google but could not find much so I'm posting this question here.
What is the benefit of executing the perl script like this?
How can we make the shell script work like a "normal" shell script once we are through executing the perl code?
Here's the code:
#!/bin/ksh
#! -*- perl -*-
eval 'exec $PERLLOCATION/bin/perl -x $0 ${1+"$#"} ;'
if 0;
print "hello world\n";
# how can I make it behave like a "normal" shell script from this point onwards? What needs to be done?
# echo "hello world" ### this results in error
This idiom is described in the perlrun documentation.
The -x switch scans the whole file and ignores anything that appears before the first line that begins with #! and also contains the word perl.
It means that your system will run the script with the Perl interpreter whether you invoke the script with perl or with a shell command (sh/bash/ksh/etc.)
That is,
$ perl this_script
and
$ sh this_script
will both run the script with perl.
To address your second question, this idiom has just about nothing to do with combining shell script and Perl script in the same file. There are a few different ways to approach that problem, but maybe the most readable way is to write in shell script, but use the shell's heredoc notation to invoke perl code.
#!/bin/bash
# this is a bash script, but there is some Perl in here too
echo this line is printed from the shell
echo now let\'s run some Perl
perl <<EOF
# this is now perl script until we get to the EOF
print "This line is printed from Perl\n";
EOF
echo now this is from the shell script again
1. If you start a Perl script in the usual way:
#!/usr/bin/perl
print "hello world\n";
the #! line will only work if the Perl interpreter is actually installed under /usr/bin. The perl/ksh bilingual script you show is a tricky kluge to make the script work even if perl is installed somewhere else. For more information, see e.g. this.
2. You can't. When the shell process encounters the exec command, it terminates and hands control over to perl. (Technically, it executes perl in place of the shell, without creating a new process.) The only way to run more shell commands after that would be to launch a new shell.
It's way simpler than what's already been posted.
#!$PERLLOCATION/bin/perl
doesn't work because the shebang (#!) line is interpreted by the kernel (not the shell), and the kernel doesn't do variable interpolation.
The code invokes ksh to expand the environment variable and to launch the specified installation of Perl.

How can I run a Perl script on Mac OS X?

How do I run a Perl script on OS X?
You can run your Perl script by invoking the Perl interpreter and giving your file as input:
perl myprogram.pl
The easiest way to run a perl script is with the option:
perl myprogram.pl
However, you may find it more useful to add a shebang line at the top of the perl file.
#!/usr/bin/perl
print "Hello World!\n";
In order to execute this script, you need to add execute permissions to your program. Run:
chmod +x myprogram.pl
Now, in order to run your script, you can simply type:
./myprogram.pl
A good tutorial on Perl in OSX can be found here:
http://www.mactech.com/articles/mactech/Vol.18/18.09/PerlforMacOSX/index.html
A generic documentation on executing Perl code is of course perldoc perlrun.
To answer your question directly:
You can run a perl script on any Unix system by either having the code evaluated and executed from command line:
perl -e 'print "Hello World\n"';
Or you can save your Perl script to a file (customarily having .pl extension, say script1.pl and with the first line being #!/usr/bin/perl) and then you can execute it as any Unix program (after setting proper execute permissions)
/path/to/script/script1.pl
You can also execute a script from a file by running perl interpreter as the command and giving the script as a parameter (in this case execute permissions to the script are not needed):
perl /path/to/script/script1.pl
For some reason the whole directory didn't work for me but I just did
perl ~/Desktop/file.pl
(you could also use any folder that is in your user-folder after the ~/)

How can I start an interactive console for Perl?

How can I start an interactive console for Perl, similar to the irb command for Ruby or python for Python?
You can use the perl debugger on a trivial program, like so:
perl -de1
Alternatively there's Alexis Sukrieh's Perl Console application, but I haven't used it.
Not only did Matt Trout write an article about a REPL, he actually wrote one - Devel::REPL
I've used it a bit and it works fairly well, and it's under active development.
BTW, I have no idea why someone modded down the person who mentioned using "perl -e" from the console. This isn't really a REPL, true, but it's fantastically useful, and I use it all the time.
I wrote a script I call "psh":
#! /usr/bin/perl
while (<>) {
chomp;
my $result = eval;
print "$_ = $result\n";
}
Whatever you type in, it evaluates in Perl:
> gmtime(2**30)
gmtime(2**30) = Sat Jan 10 13:37:04 2004
> $x = 'foo'
$x = 'foo' = foo
> $x =~ s/o/a/g
$x =~ s/o/a/g = 2
> $x
$x = faa
If you want history, use rlwrap. This could be your ~/bin/ips for example:
#!/bin/sh
echo 'This is Interactive Perl shell'
rlwrap -A -pgreen -S"perl> " perl -wnE'say eval()//$#'
And this is how it looks like:
$ ips
This is Interactive Perl shell
perl> 2**128
3.40282366920938e+38
perl>
I think you're asking about a REPL (Read, Evaluate, Print, Loop) interface to perl. There are a few ways to do this:
Matt Trout has an article that describes how to write one
Adriano Ferreira has described some options
and finally, you can hop on IRC at irc.perl.org and try out one of the eval bots in many of the popular channels. They will evaluate chunks of perl that you pass to them.
I use the command line as a console:
$ perl -e 'print "JAPH\n"'
Then I can use my bash history to get back old commands. This does not preserve state, however.
This form is most useful when you want to test "one little thing" (like when answering Perl questions). Often, I find these commands get scraped verbatim into a shell script or makefile.
There isn't an interactive console for Perl built in like Python does. You can however use the Perl Debugger to do debugging related things. You turn it on with the -d option, but you might want to check out 'man perldebug' to learn about it.
After a bit of googling, there is a separate project that implements a Perl console which you can find at
Perl Console - Perl code interactive evaluator with completion.
Hope this helps!
There are two popular Perl REPLs.
Devel::REPL is great.
But IMO Reply is better.
For reply just run it as a command. The module install the reply script. If you had installed the module and you don't have the command, check your PATH variable.
$ reply --help
reply [-lb] [-I dir] [-M mod] [--version] [--help] [--cfg file]
You can always just drop into the built-in debugger and run commands from there.
perl -d -e 1
I've created perli, a Perl REPL that runs on Linux, macOS, and Windows.
Its focus is automatic result printing, convenient documentation lookups, and easy
inspection of regular-expression matches.
You can see screenshots here.
It works stand-alone (has no dependencies other than Perl itself), but installation of rlwrap is strongly recommended so as to support command-line editing, persistent command history, and tab-completion - read more here.
Installation
If you happen to have Node.js installed:
npm install -g perli
Otherwise:
Unix-like platforms: Download this script as perli to a folder in your system's path and make it executable with chmod +x.
Windows: Download the this script as perli.pl (note the .pl extension) to a folder in your system's path.
If you don't mind invoking Perli as perli.pl, you're all set.
Otherwise, create a batch file named perli.cmd in the same folder with the following content: #%~dpn.pl %*; this enables invocation as just perli.
Perl doesn't have a console but the debugger can be used as one. At a command prompt, type perl -de 1. (The value "1" doesn't matter, it's just a valid statement that does nothing.)
There are also a couple of options for a Perl shell:
Archived "perlfaq3" page which contain question "Is there Perl Shell?"
For more information read perlfaq3 (current version).
perl -d is your friend:
% perl -de 0
re.pl from Devel::REPL
I always did:
rlwrap perl -wlne'eval;print$#if$#'
With 5.10, I've switched to:
rlwrap perl -wnE'say eval()//$#'
(rlwrap is optional)
You could look into psh here: http://gnp.github.io/psh/
It's a full on shell (you can use it in replacement of bash for example), but uses perl syntax.. so you can create methods on the fly etc.
Read-eval-print loop:
$ perl -e'while(<>){print eval,"\n"}'
Update: I've since created a downloadable REPL - see my other answer.
With the benefit of hindsight:
The third-party solutions mentioned among the existing answers are either cumbersome to install and/or do not work without non-trivial, non-obvious additional steps - some solutions appear to be at least half-abandoned.
A usable REPL needs the readline library for command-line-editing keyboard support and history support - ensuring this is a trouble spot for many third-party solutions.
If you install CLI rlwrap, which provides readline support to any command, you can combine it with a simple Perl command to create a usable REPL, and thus make do without third-party REPL solutions.
On OSX, you can install rlwrap via Homebrew with brew install rlwrap.
Linux distros should offer rlwrap via their respective package managers; e.g., on Ubuntu, use sudo apt-get install rlwrap.
See Ján Sáreník's answer for said combination of rlwrap and a Perl command.
What you do NOT get with Ján's answer:
auto-completion
ability to enter multi-line statements
The only third-party solution that offers these (with non-trivial installation + additional, non-obvious steps), is psh, but:
it hasn't seen activity in around 2.5 years
its focus is different in that it aims to be a full-fledged shell replacement, and thus works like a traditional shell, which means that it doesn't automatically evaluate a command as a Perl statement, and requires an explicit output command such as print to print the result of an expression.
Ján Sáreník's answer can be improved in one way:
By default, it prints arrays/lists/hashtables as scalars, i.e., only prints their element count, whereas it would be handy to enumerate their elements instead.
If you install the Data::Printer module with [sudo] cpan Data::Printer as a one-time operation, you can load it into the REPL for use of the p() function, to which you can pass lists/arrays/hashtables for enumeration.
Here's an alias named iperl with readline and Data::Printer support, which can you put in your POSIX-like shell's initialization file (e.g., ~/.bashrc):
alias iperl='rlwrap -A -S "iperl> " perl -MData::Printer -wnE '\''BEGIN { say "# Use `p #<arrayOrList>` or `p %<hashTable>` to print arrays/lists/hashtables; e.g.: `p %ENV`"; } say eval()//$#'\'
E.g., you can then do the following to print all environment variables via hashtable %ENV:
$ iperl # start the REPL
iperl> p %ENV # print key-value pairs in hashtable %ENV
As with Ján's answer, the scalar result of an expression is automatically printed; e.g.:
iperl> 22 / 7 # automatically print scalar result of expression: 3.14285714285714
Under Debian/Ubuntu:
$ sudo apt-get install libdevel-repl-perl
$ re.pl
$ sudo apt-get install libapp-repl-perl
$ iperl
Matt Trout's overview lists five choices, from perl -de 0 onwards, and he recommends Reply, if extensibility via plugins is important, or tinyrepl from Eval::WithLexicals, for a minimal, pure-perl solution that includes readline support and lexical persistence.
See also Stylish REPL (for GNU Emacs)
Also look for ptkdb on CPAN:
http://search.cpan.org/search?query=ptkdb&mode=all
Sepia and PDE have also own REPLs (for GNU Emacs).
You can do it online (like many things in life) here:
https://www.tutorialspoint.com/execute_perl_online.php
You can use org-babel in emacs; Open an org-mode file, i.e., tmp.org, and then you can do:
#+begin_src perl :results output
#a = (1,5,9);
print ((join ", ", #a) . "\n");
$b = scalar #a;
print "$#a, $b\n";
print "$#a, " . #a . "\n";
print join ", ", 1..$#a; print "\n";
print join ", ", #a[0..$#a]
#+end_src
Pressing CTRL-c CTRL-c evals the block:
#+RESULTS:
#+begin_example
1, 5, 9
2, 3
2, 3
1, 2
1, 5, 9
#+end_example
I am not sure what emacs config this needs to work, but I think you can just install https://github.com/hlissner/doom-emacs and enable its perl and org-mode modules.