Use of "-w" in the shebang line - perl

I am new to perl scripting and I am wondering what is the use of "-w" in hashbang of perl scripts.
#!/usr/bin/perl -w
my $userid = $ENV{USER};
print "$userid\n";
I know that this part #!/usr/bin/perl is used to inform shell that it is a perl script so that no need to use perl before running the script.
But I couldn't find the exact meaning for -w and most of the scripts I saw have this option .
Kindly let me know if that has any significance as I could not find any difference.
Edit:
Below document is very helpful(Suggested by #Toto)
https://perldoc.perl.org/5.32.0/perlrun.html

Everything after the command is passed as arguments to the command being invoked.
The -w option to the perl command is to enable warnings.

Related

Printing the result of the script(running in background) on the terminal

I am writing a perl script which runs another tcl script from it. The terminal doesn't print anything and waits for the tcl script to complete.
`chmod +x runme.tcl`; `./runme.tcl 2>&1`;
Can anyone please help me on how to print the results of the tcl script on the terminal instead of just waiting for it to get completed?
Thank you
system('chmod +x runme.tcl');
system('/runme.tcl 2>&1');
You can run tcl scripts directly from perl using the Tcl module without having to mess around with qx or system:
#!/usr/bin/env perl
use warnings;
use strict;
use Tcl;
Tcl->new->EvalFile("runme.tcl");
It'll share the same standard output as the perl script.
If you're using a new enough version of Tcl, you can easily create a safe interpreter to evaluate the script in case it tries to do anything nasty:
#!/usr/bin/env perl
use warnings;
use strict;
use Tcl v1.05;
my $interp = Tcl->new;
my $safeinterp = $interp->CreateSlave("safeinterp", 1);
$interp->Eval('interp share {} stdout safeinterp');
$interp->Eval('interp share {} stderr safeinterp');
$safeinterp->EvalFile("runme.tcl");
Backticks capture the output of an external command. You can write that output with a print command in front of the backticks.
`chmod +x runme.tcl`; print `./runme.tcl 2>&1`;

Suppress passed test output in Test::More

I have a Perl unit test that outputs "ok" for every passed test. I find myself scrolling up and up to find the first failed test, since that's the only thing I'm interested in. I am using Test::More.
use strict; use warnings;
use JSONRegex;
use Test::More;
I would like only failed tests to appear. I tried the solution of using
perl -MTest::Harness -e 'runtests #ARGV' path/to/test_JSONRegex.pl
and it worked. But I wanted to put that in the shebang line so I could just forget about it. The shebang
#!/usr/bin/env perl -MTest::Harness
failed with message Too late for "-MTest::Harness" option at ./test_JSONRegex.pl line 1.
What is the best way to suppress passed test output while still using strict in my script?
Why not just use the prove command to run your test script?
prove path/to/test_JSONRegex.pl
is basically equivalent to
perl -MTest::Harness -e 'runtests #ARGV' path/to/test_JSONRegex.pl
but with less typing.
Trying to get the test script to automatically determine whether it's already running inside a test harness is going to be tricky and error prone.
-MTest::Harness
simply puts
use Test::Harness;
at the top of your script. But then what? How do you plan on calling runtests? This is oh-so-very wrong. If you want to save typing, use prove as #cjm mentioned, or create a second small script to run your tests.
#!/bin/sh
# This is path/to/test_JSONRegex
BASE="$( dirname "$( readlink -e "$0" )" )"
perl -MTest::Harness -e'runtests #ARGV' "$BASE/test_JSONRegex.pl"
Show only errors during testing:
Test::More->builder->output("/dev/null") #

Unable to parse command line long options

#!/usr/bin/perl -sw
use strict;
use warnings;
use Getopt::Long;
my $remote = 0;
my $test = 0;
GetOptions ('remote' => \$remote, 'test' => \$test);
print "$remote:$test\n";
perl test.pl --remote --test
The above prints "0:0". I am new to Perl so I have been unable to determine why this isn't working.
I also ran the "Simple Options" section from http://perldoc.perl.org/Getopt/Long.html#Simple-options and that didn't produce anything either.
I believe the -s command line option you include on your she-bang line is biting you. According to the perlrun documentation, the -s command line option:
enables rudimentary switch parsing for switches on the command line after the program name but before any filename arguments (or before an argument of --).
If you remove that option, things should work as you expect. I would also recommend removing the -w since you are already using the use warnings directive (the use warnings directive is much more fully featured, essentially replacing the -w option).
So, long story short, make your first line:
#!/usr/bin/perl
Note that if running the script on Windows via cmd you must specify perl before the script name otherwise GetOptions doesn't work.
When I tried simply calling my script.pl on the command line without first putting perl the script ran but all the options weren't parsed.

Can I do without the shebang line in my Unix Perl scripts?

Can I write a Perl program where my first line is not #!/path/?
Thank you.
The shebang (#!)is only necessary if you want to invoke the script directly at a shell prompt, e.g. ./yourscript. You can always do perl yourscript and skip the shebang.
If your concern is hard-coding a constant path (e.g. #!/usr/bin/perl as opposed to #!/usr/local/bin/perl), then use:
#!/usr/bin/env perl
This allows the Perl interpreter to be sought in your PATH, making your scripts a bit more portable (Windows aside).
Yes, from perldoc perlrun (under the -S switch):
#!/bin/sh
eval 'exec /usr/bin/perl -wS $0 ${1+"$#"}'
if $running_under_some_shell;
See that documentation for the complete story.
If you do that then you'll need to invoke Perl explicitly. If that line is there, then the system knows that it is a Perl script so when you make the script executable you can just write ./script

Why can't I run a Perl program from TextMate?

I'm following a bioinformatics text, and this represents one of my first Perl scripts. While in TextMate, this does not produce any result. Is it functioning? I added "hello world" at the bottom and I don't see that when I run the script in TextMate. What have I done wrong?
#!/usr/local/bin/perl -w
use lib "/Users/fogonthedowns/myperllib";
use LWP::Simple;
use strict;
#Set base URL for all eutils
my $utils = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils";
my $db = "Pubmed";
my $query ="Cancer+Prostate";
my $retmax = 10;
my $esearch = "$utils/esearch.fcgi?" .
"db=$db&retmax=$retmax&term=";
my $esearch_result = get($esearch.$query);
print "ESEARCH RESULT: $esearch_result\n";
print "Using Query: \n$esearch$query\n";
print "hello world\n";
Have you run other scripts successfully in TextMate? I suspect that you have an editor configuration issue (or that URL is not hittable and the script is generating an error).
Try running an even simpler script and see what happens, e.g. something like:
#!/usr/local/bin/perl -w
print "hello world\n";
Next, see if you can see error output:
#!/usr/local/bin/perl -w
warn "oh noes";
Most likely, your executing environment is not set up in the right way, i.e., TextMate does not know how to execute a Perl script and display the results to you. Have you tried running it from the shell?
Do you have /usr/local/bin/perl installed? What does which perl return at the terminal?
If your hashbang line is incorrect then when you come to run the script in TextMate you will just get an empty output window. Textmate does not give any error that it couldn't find the executable interpreter you prescribed after #! :(
Replace the first line with #!/usr/bin/env perl and it will run you login's default Perl (found in $PATH environment variable).
/I3az/