Pod::Usage not working correctly - perl

I have:
my $man = 0;
my $help = 0;
## Parse options and print usage if there is a syntax error,
## or if usage was explicitly requested.
GetOptions('help|?' => \$help, man => \$man) or pod2usage(2);
pod2usage(1) if $help;
pod2usage(-verbose => 2) if $man;
#-----------------------------------------------------------------
#---------------- Documentation / Usage / Help ------------------
=head1 NAME
sample - Using GetOpt::Long and Pod::Usage
=head1 SYNOPSIS
sample [options] [file ...]
Options:
-help brief help message
-man full documentation
=head1 OPTIONS
=over 8
=item B<-help>
Print a brief help message and exits.
=item B<-man>
Prints the manual page and exits.
=back
=head1 DESCRIPTION
B<This program> will read the given input file(s) and do something
useful with the contents thereof.
=cut
Pretty much copy / pasted from the online example. However, when I do script.pl --help nothing prints, and the script exits.

As has been stated, the spacing of pod documentation matters. Additionally, it's not necessary to duplicate your options in the synopsis, instead just leave them in the options section.
The following is a cleaned up version of your trial usage of Pod::Usage
use strict;
use warnings;
use Getopt::Long qw(GetOptions);
use Pod::Usage qw(pod2usage);
## Parse options and print usage if there is a syntax error,
## or if usage was explicitly requested.
GetOptions(
'help|?' => \my $help,
'man' => \my $man,
) or pod2usage(-verbose => 0);
pod2usage(-verbose => 1) if $help;
pod2usage(-verbose => 2) if $man;
## Check for File
pod2usage("$0: No filename specified.\n") unless #ARGV;
#-----------------------------------------------------------------
#---------------- Documentation / Usage / Help ------------------
=head1 NAME
sample - Using GetOpt::Long and Pod::Usage
=head1 SYNOPSIS
sample [file]
=head1 OPTIONS
=over 8
=item B<--help>
Print a brief help message and exits.
=item B<--man>
Prints the manual page and exits.
=back
=head1 DESCRIPTION
B<This program> will read the given input file(s) and do something
useful with the contents thereof.
=cut

Miller has the answer.
When you create POD documentation, you need a blank line between each paragraph including the command paragraphs. The POD Documentation does not make that clear. Also, all POD command paragraphs must start in the first column. For example, this is wrong:
=head1 NAME
foo.cmd
=head1 DESCRIPTION
This is my description of my command.
....
I need to space this out:
=head1 NAME
foo.cmd
=head1 DESCRIPTION
This is my description.
Otherwise, POD would interpret it this way:
=head1 NAME foo.cmd =head1 DESCRIPTION This is my description of my command.
Now, you don't have a header named NAME or DESCRIPTION, so your pod2usage won't print.
I also need to start my commands on column 1. This won't work:
=over 4
=item *
blah, blah, blah...
I need to do this:
=over 4
=item *
blah, blah, blah
=back
You can run the podchecker program to check your pod and make sure everything is correct. This should be in the same directory as the perl command. I put your pod documentation into test.pod and ran this command:
$ podchecker test.pod
*** WARNING: empty section in previous paragraph at line 4 in file test.pod
*** WARNING: empty section in previous paragraph at line 10 in file test.pod
*** ERROR: Apparent command =cut not preceded by blank line at line 21 in file test.pod
*** WARNING: empty section in previous paragraph at line 18 in file test.pod
test.pod has 1 pod syntax error.
The empty section in previous paragraph warnings come from not skipping a line after =head1.

Related

How can I pass one more argument to a Perl script? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
The test_prop.pl file currently accepts one argument:
my %options=();
getopts("i:", \%options);
$inputconf = $options{i};
This Perl script is getting called from a shell script as shown below:
perl test_prop.pl -i $FILE
I would like to pass one more argument to this perl script. How can I achieve that?
Following my template demonstrates how to handle multiple options, documenting the code for brief and full information.
#!/usr/bin/perl
#
# Description:
# Describe purpose of the program
#
# Parameters:
# Describe parameters purpose
#
# Date: Tue Nov 29 1:18:00 UTC 2019
#
# Author: Polar Bear
# https://stackoverflow.com/users/12313309/polar-bear
#
use strict;
use warnings;
use Getopt::Long qw(GetOptions);
use Pod::Usage;
my %opt;
my #args = (
'input|i=s',
'output|o=s',
'debug|d',
'help|?',
'man|m'
);
GetOptions( \%opt, #args ) or pod2usage(2);
print Dumper(\%opt) if $opt{debug};
pod2usage(1) if $opt{help};
pod2usage(-exitval => 0, -verbose => 2) if $opt{man};
pod2usage("$0: No files given.") if ((#ARGV == 0) && (-t STDIN));
__END__
=head1 NAME
program - brief on program's purpose
=head1 SYNOPSIS
program.pl [options] file(s)
Options:
-i,--input input filename
-o,--output output filename
-d,--debug output debug information
-?,--help brief help message
-m,--man full documentation
=head1 OPTIONS
=over 4
=item B<-i,--input>
Input filename
=item B<-o,--output>
Output filename
=item B<-d,--debug>
Print debug information.
=item B<-?,--help>
Print a brief help message and exits.
=item B<--man>
Prints the manual page and exits.
=back
=head1 DESCRIPTION
B<This program> accepts B<input> and processes to B<output> with purpose of achiving some goal.
=head1 EXIT STATUS
The section describes B<EXIT STATUS> codes of the program
=head1 ENVIRONMENT
The section describes B<ENVIRONMENT VARIABLES> utilized in the program
=head1 FILES
The section describes B<FILES> which used for program's configuration
=head1 EXAMPLES
The section demonstrates some B<EXAMPLES> of the code
=head1 REPORTING BUGS
The section provides information how to report bugs
=head1 AUTHOR
The section describing author and his contanct information
=head1 ACKNOWLEDGMENT
The section to give credits people in some way related to the code
=head1 SEE ALSO
The section describing related information - reference to other programs, blogs, website, ...
=head1 HISTORY
The section gives historical information related to the code of the program
=head1 COPYRIGHT
Copyright information related to the code
=cut
OP's post does not specify where getopts() is originated from
Let's assume getopts() originates from Getopts::Std
use strict;
use warnings;
use feature 'say';
use Getopt::Std;
use Data::Dumper;
$Getopt::Std::STANDARD_HELP_VERSION = 1;
my $version = '0.02';
my %opts;
getopts('iodn:',\%opts);
say 'INFO: -i input' if $opts{i};
say 'INFO: -o output' if $opts{o};
say "INFO: -n net $opts{n}" if $opts{n};
say Dumper(\%opts) if $opts{d};
my $fname = shift;
say "INFO: filename $fname" if $fname;
sub HELP_MESSAGE {
say "
This program performs specific task
USAGE:
program.pl [options] file(s)
-i input flag
-o output flag
-n dns network name
-d debug flag
";
}
sub VERSION_MESSAGE {
say "
program.pl Vesion $version 2020
";
}
Run the program as program.pl -i -o -0 something
Unknown option: 0
INFO: -i input
INFO: -o output
INFO: filename something
Run the program as program.pl -i -o -d something
INFO: -i input
INFO: -o output
$VAR1 = {
'd' => 1,
'o' => 1,
'i' => 1
};
INFO: filename something
Run the program as program.pl -i -o -d -n something
INFO: -i input
INFO: -o output
INFO: -n net something
$VAR1 = {
'd' => 1,
'i' => 1,
'n' => 'something',
'o' => 1
};
Run the program as program.pl --help
program.pl Vesion 0.02 2020
This program performs specific task
USAGE:
program.pl [options] file(s)
-i input flag
-o output flag
-n dns network name
-d debug flag
Run the program as program.pl --version
program.pl Vesion 0.02 2020
Documentation: Getopts::Std

How to document parameters in Perl POD

I have this POD:
=head1 My code
=head2 check
Checks something.
Parameters:
=over 8
=item what to check.
=back
=cut
podchecker doesn't complain. perldoc shows this:
My code
check
Checks something.
Parameters:
what to check.
I expected the "what to check" line to be indented further.
How do I need to change my POD to show parameters indented?
Is there a better way to do this than with =items?
Both perldoc and pod2html ignore the indentlevel. Use bullets as a workaround. See an example below.
=head1 My code
=head2 check with no bullets or numbers
Checks something.
Parameters:
=over
=item what to check A
=item what to check B
=back
=head2 check with bullets
Checks something.
=over
=item * what to check A
=item * what to check B
=back
=head2 check with numbers
Checks something.
=over
=item 1. what to check A
=item 2. what to check B
=back
=cut
Running perldoc /path/to/script.pl results in this:
My code
check with no bullets or numbers
Checks something.
Parameters:
what to check A
what to check B
check with bullets
Checks something.
o what to check A
o what to check B
check with numbers
Checks something.
1. what to check A
2. what to check B
REFERENCES:
The indentlevel option to "=over" indicates how far over to indent,
generally in ems (where one em is the width of an "M" in the
document's base font) or roughly comparable units; if there is no
indentlevel option, it defaults to four. (And some formatters may just
ignore whatever indentlevel you provide.)
(From perldoc perlpod, boldface mine)
Please study my template code, you will require to have Getopt::Long and Pod::Usage installed.
You will be able to run this script with options --man and --help to generate brief and full documentation.
#!/usr/bin/perl
#
# Description:
# Describe purpose of the program
#
# Parameters:
# Describe parameters purpose
#
# Date: Tue Nov 29 1:18:00 UTC 2019
#
# Author: Polar Bear
# https://stackoverflow.com/users/12313309/polar-bear
#
use strict;
use warnings;
use Getopt::Long qw(GetOptions);
use Pod::Usage;
use Data::Dumper;
my %opt;
my #args = (
'input|i=s',
'output|o=s',
'debug|d',
'help|?',
'man|m'
);
GetOptions( \%opt, #args ) or pod2usage(2);
print Dumper(\%opt) if $opt{debug};
pod2usage(1) if $opt{help};
pod2usage(-exitval => 0, -verbose => 2) if $opt{man};
pod2usage("$0: No files given.") if ((#ARGV == 0) && (-t STDIN));
__END__
=head1 NAME
program - brief on program's purpose
=head1 SYNOPSIS
program.pl [options] file(s)
Options:
-i,--input input filename
-o,--output output filename
-d,--debug output debug information
-?,--help brief help message
-m,--man full documentation
=head1 OPTIONS
=over 4
=item B<-i,--input>
Input filename
=item B<-o,--output>
Output filename
=item B<-d,--debug>
Print debug information.
=item B<-?,--help>
Print a brief help message and exits.
=item B<--man>
Prints the manual page and exits.
=back
=head1 DESCRIPTION
B<This program> accepts B<input> and processes to B<output> with purpose of achiving some goal.
=head1 EXIT STATUS
The section describes B<EXIT STATUS> codes of the program
=head1 ENVIRONMENT
The section describes B<ENVIRONMENT VARIABLES> utilized in the program
=head1 FILES
The section describes B<FILES> which used for program's configuration
=head1 EXAMPLES
The section demonstrates some B<EXAMPLES> of the code
=head1 REPORTING BUGS
The section provides information how to report bugs
=head1 AUTHOR
The section describing author and his contanct information
=head1 ACKNOWLEDGMENT
The section to give credits people in some way related to the code
=head1 SEE ALSO
The section describing related information - reference to other programs, blogs, website, ...
=head1 HISTORY
The section gives historical information related to the code of the program
=head1 COPYRIGHT
Copyright information related to the code
=cut
Man page script.pl --man
NAME
program - brief on program's purpose
SYNOPSIS
program.pl [options] file(s)
Options:
-i,--input input filename
-o,--output output filename
-d,--debug output debug information
-?,--help brief help message
-m,--man full documentation
OPTIONS
-i,--input
Input filename
-o,--output
Output filename
-d,--debug
Print debug information.
-?,--help
Print a brief help message and exits.
--man
Prints the manual page and exits.
DESCRIPTION
This program accepts input and processes to output with purpose of
achiving some goal.
EXIT STATUS
The section describes EXIT STATUS codes of the program
ENVIRONMENT
The section describes ENVIRONMENT VARIABLES utilized in the program
FILES
The section describes FILES which used for program's configuration
EXAMPLES
The section demonstrates some EXAMPLES of the code
REPORTING BUGS
The section provides information how to report bugs
AUTHOR
The section describing author and his contanct information
ACKNOWLEDGMENT
The section to give credits people in some way related to the code
SEE ALSO
The section describing related information - reference to other
programs, blogs, website, ...
HISTORY
The section gives historical information related to the code of the
program
COPYRIGHT
Copyright information related to the code
Help page script.pl --help
program.pl [options] file(s)
Options:
-i,--input input filename
-o,--output output filename
-d,--debug output debug information
-?,--help brief help message
-m,--man full documentation
Options:
-i,--input
Input filename
-o,--output
Output filename
-d,--debug
Print debug information.
-?,--help
Print a brief help message and exits.
--man
Prints the manual page and exits.

How to call a perl script from another perl script and transfer parameter?

I'm trying to call a perl script from another perl script, and transfer the parameter to it.
For example:
there is a script: main.pl
I use command line to run this script, and give a value to parameter "$directory", then I call another perl script "sub.pl". I want to pass the value of "$directory" to the parameter "$path" from sub.pl.
(in brief, sub.pl has the parameter $path, main.pl has the parameter $directory, I want to call sub.pl in main.pl, and pass the $directory value to $path)
Sorry for my verbose description...Anyway, which function can do this job? Thanks.
You did not provide any sample of code you have tried -- how can we know what is your vision of the code?
Ok, bellow I provide a sample of main script dir_main.pl and secondary script dir_sub.pl just for demonstration purpose how I would do it.
Both scripts can be run with parameters '--help' (-h) or '--man' (-m) to obtain help and man page describing usage and full documentation for the scripts. Script dir_sub.pl has extra option '--debug' (-d) to print content of options hash.
USAGE: perl dir_main.pl --dir c:\Users -- Windows
USAGE: dir_main.pl --dir /usr/home -- Linux
NOTE:
in Linux both scripts should be made executable with following command chmod og+x dir_main.pl dir_sub.pl before they can run from shell without specifying perl
(shell knows from shebang that the scripts should be run with perl interpreter)
Source code of: dir_main.pl
#!/usr/bin/perl
#
# DESCRIPTION:
# Sample code 'dir_main.pl' written for StackOverflow
#
# DATE:
# Jan 10, 2020
#
# AUTHOR:
# Polar Bear <https://stackoverflow.com/users/12313309/polar-bear>
#
use strict;
use warnings;
use Getopt::Long qw(GetOptions);
use Pod::Usage;
my %opt;
GetOptions(
'dir|d=s' => \$opt{dir},
'help|h' => \$opt{help},
'man|m' => \$opt{man}
) or pod2usage(2);
pod2usage(1) if $opt{help};
pod2usage(-exitval => 0, -verbose => 2) if $opt{man};
system('perl','.\dir_sub.pl','--path',$opt{dir}) if $opt{dir};
exit 0;
=pod
=head1 NAME
program.pl - short description of the program
=head1 SYNOPSIS
program.pl [options]
Options:
--dir,-d input directory
--help,-h brief help message
--man,-m full documentation
=head1 OPTIONS
=over 4
=item B<--dir|-d>
Input directory
=item B<--help|-h>
Print a brief help message and exit
=item B<--man|-m>
Prints the manual page and exit
=back
=head1 DESCRIPTION
B<This program> surve some purpose to produce pre-defined result
=head1 AUTHOR
Polar Bear Jan 10, 2020
=head1 REPORTING BUGS
E-mail L<mailto:bugs#inter.net>
=head1 COPYRIGHT
Copyright information
=head1 SEE ALSO
L<The Perl Home page|http://www.perl.org/>
=cut
Source code of: dir_sub.pl
#!/usr/bin/perl
#
# DESCRIPTION:
# Sample code 'dir_sub.pl' written for StackOverflow
#
# DATE:
# Jan 10, 2020
#
# AUTHOR:
# Polar Bear <https://stackoverflow.com/users/12313309/polar-bear>
#
use strict;
use warnings;
use feature 'say';
use Getopt::Long qw(GetOptions);
use Pod::Usage;
use Data::Dumper;
my %opt;
GetOptions(
'path|p=s' => \$opt{path},
'help|h' => \$opt{help},
'man|m' => \$opt{man},
'debug|d' => \$opt{debug}
) or pod2usage(2);
pod2usage(1) if $opt{help};
pod2usage(-exitval => 0, -verbose => 2) if $opt{man};
print Dumper(\%opt) if $opt{debug};
list($opt{path}) if $opt{path};
sub list {
my $path = shift;
opendir my $dh, $path
or die "ERROR: opendir couldn't open $path";
map{ say $_ } readdir($dh);
close $dh;
}
exit 0;
=pod
=head1 NAME
program.pl - short description of the program
=head1 SYNOPSIS
program.pl [options]
Options:
--path,-p input path to list
--help,-h brief help message
--man,-m full documentation
--debug,-d debug information
=head1 OPTIONS
=over 4
=item B<--path|-p>
Input path to list files
=item B<--help|-h>
Print a brief help message and exit
=item B<--man|-m>
Prints the manual page and exit
=item B<--debug|-d>
Prints the debug information
=back
=head1 DESCRIPTION
B<This program> surve some purpose to produce pre-defined result
=head1 AUTHOR
Polar Bear Jan 10, 2020
=head1 REPORTING BUGS
E-mail L<mailto:bugs#inter.net>
=head1 COPYRIGHT
Copyright information
=head1 SEE ALSO
L<The Perl Home page|http://www.perl.org/>
=cut
Very first question: does sub.pl have a mechanism for setting $path from the command-line?
If not, you're not going to do it: you can't arbitrarily set an internal variable to some value... that would open up all sorts of security risks & dangers to any piece of code!
Assuming you can call something like sub.pl path=/my/path then it's easy
(but I have horrible suspicion you mean the former!)

Compilation error wile using pod2usage in perl

I have a file which accepts a file as an argument and does some operation on it.
#!/usr/bin/perl
use strict;
use warnings;
use Date::Format;
use Pod::Usage;
###################
#USAGE
###################
=head1 SYNOPSIS
perl my-file.pl <log file name>
Options:
-help Prints usage synopsis of this program.
-man Man page for this program.
Use option "-man" for extended usage help.
=head1 ARGUMENTS
=over 1
=item 1 Log File Name
Enter name of the log file. This is a required argument.
=cut
print "\n\n";
GetOptions('help|?' => \$help, man => \$man) or pod2usage(2);
pod2usage(1) if $help;
pod2usage(-verbose => 2) if $man;
pod2usage("$0: Insufficient arguments given. Please see the usage below...") if (#ARGV == 0);
my $logfile = $ARGV[0];
my $cmd;
my $n;
$cmd = q(awk '!/Jobs still running./' $logfile > temp.txt && mv temp.txt $logfile);
$n = system($cmd)
;
While running this file I am getting the below compilation error. Not sure what is the reason for this error as another file with similar format work fine.
Global symbol "$help" requires explicit package name at mv-workitem-LogWatcher.pl line 33.
Global symbol "$man" requires explicit package name at mv-workitem-LogWatcher.pl line 33.
Global symbol "$help" requires explicit package name at mv-workitem-LogWatcher.pl line 34.
Global symbol "$man" requires explicit package name at mv-workitem-LogWatcher.pl line 35.
my-file.pl had compilation errors
.
You turned on strict but failed to declare your variables. You usually do this with my. Here's some more about my and lexical scoping of variables.
I'd recommend picking up a copy of Modern Perl or Beginning Perl.
You are getting errors because you are using use strict in your code but you didn't declare any varibale.
To understand variable declaration read this tutorial Variable declaration in Perl.

How can I get rid of empty lines Perl's Pod so they don't show up with Pod::Usage?

I have following pod which I used with getopt::long:
=head1 SYNOPSIS
foo [OPTION]... [URL]...
=head1 OPTIONS
=over 20
=item B<-h, --help>
Print a brief help message and exits.
=item B<-i, --input=FILE>
Reads from FILE
=back
=cut
and when I provides -h it produces:
Usage:
foo [OPTION]... [URL]...
Options:
-h, --help Print a brief help message and exits.
-i, --input=FILE Reads from FILE
My question is: how can I remove empty line between -h and -i ?
Pod::Usage just calls a Pod formatter like perldoc or Text::Pod to generate the usage messages from your Pod. The Pod code you've written will be formatted with a couple of empty lines by those tools. If you don't want those, write different Pod. For example
=over 4
=item B<-h> Print a brief help message and exits.
=item B<-i>, B<--input=FILE> Reads from FILE
=back
Unfortunately that won't look as nice when being converted into other formats such as HTML, and you're losing the nice vertical alignment of options and their descriptions. However, as Pod::Usage is really intended for command-line programs, it seems to be reasonable to optimise for readability of text on a terminal instead of having things look good in HTML or similar.