(view source code of allhelp.pl as plain text)
#!/usr/bin/perl
# allhelp.pl for Linux
# Display help for the Bourne Shell's internal commands and reserved words
# Written by Rob van der Woude
# http://www.robvanderwoude.com
use strict;
use warnings;
use Config;
use CGI qw(escapeHTML);
my $scriptver = '1.02';
# Abort if not running on Linux
if ( lc( $Config{osname} ) ne 'linux' ) {
print "This script will run on Linux systems only.";
exit 1;
}
my @cmds;
my @builtins;
my @coreutils;
my @reserved;
my %helplong;
my %helpshort;
my $outfile = 'allhelp_bash.html';
# Create a list of all internal commands for which help is available
open( SHELL, "-|", "bash", "-c", "compgen -b" );
while( <SHELL> ) {
chomp;
push( @builtins, $_ );
}
close( SHELL );
# Create a list of all reserved words for which help is available
open( SHELL, "-|", "bash", "-c", "compgen -k" );
while( <SHELL> ) {
chomp;
push( @reserved, $_ );
}
close( SHELL );
# Create a list of coreutils
open( SHELL, '-|', 'bash', '-c', 'info | grep -F "(coreutils)"');
while ( <SHELL> ) {
chomp;
if ( $_ =~ m/^\*\s+([a-z][a-z0-9]+):\s+\(coreutils\)\1/ ) {
$_ =~ /^\*\s+([a-z][a-z0-9]+):\s+\(coreutils\)\1\s[^.]+\.\s+(.+)$/;
push( @coreutils, $1 );
my $anchor = &Anchor( $1 );
$helpshort{ $anchor } = $2;
}
}
close( SHELL );
# Merge the lists of commands
push( @cmds, @builtins );
push( @cmds, @reserved );
push( @cmds, @coreutils );
# Sort the list of commands, punction and numbers first
@cmds = sort {
if ( $a =~ m/^[a-z]/i and $b !~ m/^[a-z]/i ) {
return 1;
} elsif ( $a !~ m/^[a-z]/i and $b =~ m/^[a-z]/i ) {
return -1;
} else {
return $a cmp $b;
}
} @cmds;
# Calculate available column width for 3 columns display with 3 characters spacing
my $cols = `tput cols`;
my $rows = `tput lines`;
my $colwidth = int( ( $cols - 6 ) / 3 );
# First display the Linux version
print &LinuxVer( ) . "\n\n";
# Display the list of commands in 3 columns
for ( my $i = 0; $i < @cmds; $i += 3 ) {
printf '%-' . $colwidth . 's', $cmds[$i];
if ( $i + 1 < @cmds ) { printf ' %-' . $colwidth . 's', $cmds[$i+1]; }
if ( $i + 2 < @cmds ) { printf ' %-' . $colwidth . 's', $cmds[$i+2]; }
print "\n";
}
# Display help for each command in the array
foreach my $cmd ( @cmds ) {
print "\nHelp for '$cmd'\n\n";
my $anchor = &Anchor( $cmd );
my $helptext = '';
if ( grep { $_ eq $cmd } @coreutils ) {
# Use info command for coreutils
open( SHELL, "-|", "bash", "-c", "info $cmd | grep -F \"\"" );
# Read resulting help text from STDOUT
while ( <SHELL> ) {
$helptext .= $_;
}
close( SHELL );
if ( $helptext ) {
$helptext =~ s/\342\200\230/'/g;
$helptext =~ s/\342\200\231/'/g;
$helptext =~ s/^\/([^\n]*\n){3}\d+\.\d+\s+//;
$helptext =~ s/\n=+\n/\n/g;
$helplong{ $anchor } = $helptext;
}
} else {
# Use help command for reserved words and builtin commands
# Escape the commands, otherwise bash may break on parenthesis
my $esccmd = quotemeta( $cmd );
# Run help command with escaped command name
open( SHELL, "-|", "bash", "-c", "help $esccmd 2> /dev/null" );
# Read resulting help text from STDOUT
while ( <SHELL> ) {
$helptext .= $_;
}
close( SHELL );
if ( "$helptext" !~ m/^\s*$/g ) {
$helplong{ $anchor } = $helptext;
# Display help text
print escapeHTML( $helptext );
# Get short help text summary
my $firstline = $cmd . ': ' . $cmd . '[^\n]*\n\s+';
if ( $cmd ne $esccmd ) {
$firstline = $esccmd . '[^a-z:\n]*: ' . $esccmd . '[^\n]*\n\s+';
}
"$helptext" =~ /$firstline((.|\n)*?)\n\s*\n/;
$helpshort{ $anchor } = $1;
}
}
}
print "\n\n";
# Remove commands from list if no help is available
# Use reverse order to prevent skipping 1 each time an element is removed from the array
for ( my $i = @cmds - 1; $i >= 0; $i-- ) {
my $cmd = $cmds[$i];
my $anchor = &Anchor( $cmd );
unless ( exists( $helplong{ $anchor } ) ) {
my $index = 0;
$index++ until $cmds[$index] eq $cmd or $index == @cmds;
splice( @cmds, $index, 1 );
}
}
# Write the help to a HTML file
my $htmlhelp = &HTMLHead( );
$htmlhelp .= &HTMLList( );
foreach my $cmd ( @cmds ) {
$htmlhelp .= &HTMLCommand( $cmd );
}
$htmlhelp .= &HTMLFoot( );
open( HTML, ">", $outfile ) or die( "Error writing HTML to file \"$outfile\"." );
print HTML $htmlhelp;
close( HTML );
# Open the newly created HTML file in the default browser (may generate warning messages with Firefox)
if ( `which sensible-browser` ) {
exec( 'sensible-browser', $outfile );
} elsif ( `which xdg-open > /dev/null` ) {
exec( 'xdg-open', $outfile );
} elsif ( `which gnome-open > /dev/null` ) {
exec( 'gnome-open', $outfile );
} elsif ( `which x-www-browser` ) {
exec( 'x-www-browser', $outfile );
} else {
my $browser = `gconftool -g /desktop/gnome/url-handlers/http/command 2> /dev/null`;
if ( $browser ) {
exec( $browser, $outfile );
} else {
die "Unable to locate default browser; open \"$outfile\" manually.";
}
}
sub Alphabet( ) {
my $html = "<table class=\"Alphabet\">\n<tr>\n";
my $found = 0;
foreach my $c ( @cmds ) {
my $A = uc( substr( $c, 0, 1 ) );
if ( $A !~ /[A-Z]/ ) {
$found = 1;
}
}
if ( $found ) {
$html .= "\t<th><a href=\"#Punc\">#</a></th>\n";
} else {
$html .= "\t<th style=\"color: gray;\">#</th>\n";
}
foreach my $a ( 'a' .. 'z' ) {
my $A = uc( $a );
my $found = 0;
foreach my $c ( @cmds ) {
if ( lc( substr( $c, 0, 1 ) ) eq $a ) {
$found = 1;
}
}
if ( $found ) {
$html .= "\t<th><a href=\"#$A\">$A</a></th>\n";
} else {
$html .= "\t<th style=\"color: gray;\">$A</th>\n";
}
}
$html .= "</tr>\n</table>\n";
return $html;
}
sub Anchor( ) {
my $cmd = $_[0];
my $firstchar = substr( $cmd, 0, 1 );
my $anchor = $cmd;
if ( $firstchar eq "." ) { $anchor = "dot"; }
if ( $firstchar eq ":" ) { $anchor = "colon"; }
if ( $firstchar eq '!' ) { $anchor = "exclamation"; }
if ( $firstchar eq "(" ) { $anchor = "parentheses"; }
if ( $firstchar eq "[" ) { $anchor = "brackets"; }
if ( $firstchar eq "{" ) { $anchor = "braces"; }
return $anchor;
}
sub HTMLCommand( ) {
my $cmd = $_[0];
my $anchor = &Anchor( $cmd );
my $type;
my $class;
if ( grep { $_ eq $cmd } @coreutils ) {
$class = 'CoreUtils';
$type = "<p><strong>coreutils</strong></p>\n\n";
} elsif ( grep { $_ eq $cmd } @builtins ) {
$class = 'BuiltIn';
$type = "<p><strong>builtin command</strong></p>\n\n";
} elsif ( grep { $_ eq $cmd } @reserved ) {
$class = 'ReservedWord';
$type = "<p><strong>reserved word</strong></p>\n\n";
} else {
$class = '';
$type = '';
}
my $html = '';
if ( $class ne '' ) {
$html .= "<div class=\"$class\">\n\n";
}
$html .= "<h2 id=\"$anchor\">$cmd</h2>\n\n$type<pre>";
$html .= escapeHTML( $helplong{ $anchor } );
$html .= "</pre>\n\n<div class=\"Center\"><a href=\"#\">Back to the top of this page</a></div>\n\n<p> </p>\n\n";
if ( $class ne '' ) {
$html .= "</div>\n\n";
}
return $html;
}
sub HTMLFoot( ) {
my @now = localtime( );
my $html = "<table>\n<tr id=\"Note\">\n\t<td class=\"Bold Top\">Note:</td>\n\t<td> </td>\n";
$html .= "\t<td>Not all reserved words are listed here, only the ones for which help is available.</td>\n</tr>\n</table>\n\n";
$html .= "<p> </p>\n\n<div class=\"Center\">\n\n<p>This HTML help was generated on ";
$html .= sprintf( "%4d-%02d-%02d", $now[5] + 1900, $now[4], $now[3] );
$html .= " by <a href=\"http://www.robvanderwoude.com/perlexamples.php#allhelp\">";
$html .= "allhelp.pl</a>, Version $scriptver<br />\n";
$html .= "Written by Rob van der Woude<br />\n";
$html .= "<a href=\"http://www.robvanderwoude.com/\">http://www.robvanderwoude.com</a></p>\n\n";
$html .= "</div>\n\n</div>\n\n</div>\n\n<p> </p>\n\n</body>\n</html>";
}
sub HTMLHead( ) {
my $title = &LinuxVer( );
my $html = <<"END_OF_HTML";
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7;FF=3;OtherUA=4">
<meta name="robots" content="index,follow">
<meta name="generator" content="allhelp.pl, Version $scriptver, by Rob van der Woude, www.robvanderwoude.com">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>Help for $title</title>
<style type="text/css">
a, a.visited
{
color: blue;
}
td.Command
{
vertical-align: top;
padding-left: 10px;
padding-right: 5px;
font-weight: bold;
white-space: nowrap;
}
th
{
vertical-align: top;
}
table.Alphabet
{
border: 2px solid blue;
margin: 0 auto 0 auto;
text-align: center;
vertical-align: middle;
width: 100%;
}
table.Alphabet th
{
padding: 5px;
width: 4%;
}
table.List
{
margin: 0 auto 0 auto;
width: 100%;
}
table.List th
{
background-color: blue;
color: white;
font-size: 120%;
font-weight: bold;
padding-left: 10px;
}
pre
{
white-space: pre-wrap;
}
.Bold
{
font-weight: bold;
}
.Center
{
text-align: center;
margin-left: auto;
margin-right: auto;
}
.Left
{
text-align: left;
}
.Smallfont
{
font-size: 60%;
}
.Top
{
vertical-align: top;
}
</style>
</head>
<body>
<h2 class="Center">Help for</h2>
<h1 class="Center">CoreUtils, internal Bash commands</h1>
<h2 class="Center">and reserved words <sup>(<a href="#Note">*</a>)</sup></h2>
<h3 class="Center">$title</h3>
<p> </p>
<div class="Center" style="width: 50em;">
<div class="Left" style="width: 50em;">
END_OF_HTML
$html .= Alphabet( );
return $html;
}
sub HTMLList( ) {
my $lastfirstchar = '';
my $html = "<table class=\"List\">\n";
$html .= "<tr id=\"Punc\">\n\t<th colspan=\"2\">Punctuation</th>\n</tr>\n";
$html .= "<tr>\n\t<td colspan=\"2\"> </td>\n</tr>\n";
foreach my $cmd ( @cmds ) {
my $firstchar = '';
if ( "$cmd" =~ m/^[a-z]/ ) {
"$cmd" =~ /^([a-z])/;
$firstchar = uc( $1 );
if ( $firstchar ) {
if ( $firstchar ne $lastfirstchar ) {
$html .= "<tr>\n\t<td colspan=\"2\"> </td>\n</tr>\n";
$html .= "<tr id=\"$firstchar\">\n\t<th colspan=\"2\">$firstchar</th>\n</tr>\n";
$html .= "<tr>\n\t<td colspan=\"2\"> </td>\n</tr>\n";
}
}
}
$lastfirstchar = $firstchar;
my $anchor = &Anchor( $cmd );
my $help = escapeHTML( $helpshort{ $anchor } );
my $class;
if ( grep { $_ eq $cmd } @coreutils ) {
$class = ' class="CoreUtils"';
} elsif ( grep { $_ eq $anchor } @builtins ) {
$class = ' class="BuiltIn"';
} elsif ( grep { $_ eq $anchor } @reserved ) {
$class = ' class="ReservedWord"';
} else {
$class = '';
}
$help =~ s/[\t ]+/ /g;
$html .= "<tr$class>\n\t<td class=\"Command\"><a href=\"#$anchor\">$cmd</a></td>\n\t<td>$help</td>\n</tr>\n";
}
$html .= "</table>\n\n<p> </p>\n\n";
return $html;
}
sub LinuxVer( ) {
my $os = '';
open( SHELL, "-|", "bash", "-c", "uname -sirv" );
while( <SHELL> ) {
chomp( $os = $_ );
}
close( SHELL );
if ( $os eq '' ) {
$os = "$Config{osname} $Config{osvers}";
}
return $os;
}
page last modified: 2024-04-16; loaded in 0.0168 seconds