shell: feature comparison table from uniq-faq
authorMischa POSLAWSKY <perl@shiar.org>
Mon, 11 Jun 2018 16:39:44 +0000 (18:39 +0200)
committerMischa POSLAWSKY <perl@shiar.org>
Mon, 11 Jun 2018 20:12:17 +0000 (22:12 +0200)
Page copied from browser.plp with unneeded features removed.
Include initialised with data from usenet unix-faq/shell/shell-differences
v1.17 (1997-07-13) by Brian Blackmore:

perl -wE'
use Data::Dump "pp";
use List::MoreUtils "mesh";
while (<>) { last if s/^ +// }  # to table start
my @cols = split /\s+/;
while (<>) {
chomp;
$_ or last;
my ($title, $support) = split /  +/, $_, 2;
my @support = split / +/, $support;
push @rows, {
title => $title,
support => { mesh(@cols, @support) },
};
}
print pp(\@rows);
'

shell.inc.pl [new file with mode: 0644]
shell.plp [new file with mode: 0644]

diff --git a/shell.inc.pl b/shell.inc.pl
new file mode 100644 (file)
index 0000000..03a312d
--- /dev/null
@@ -0,0 +1,608 @@
+use utf8;
+use strict;
+
++{
+
+agents => {
+       sh => {
+               name => "Bourne shell",
+               os => 'v7',
+       },
+       bash => {
+               name => "GNU Bourne-Again SHell",
+               os => 'linux',
+       },
+       csh => {
+               name => "C Shell",
+       },
+       tcsh => {
+               name => "Tenex C Shell",
+               os => 'freebsd',
+       },
+       ksh => {
+               name => "AT&T KornShell",
+       },
+       es => {
+               name => "Extensible Shell",
+       },
+       rc => {
+               name => "Run Commands",
+               os => 'plan9',
+       },
+       zsh => {
+               name => "Z shell",
+       },
+},
+
+feature => [
+
+       {
+               title   => "Job control",
+               description => "",
+               links => [
+                       {
+                               title =>
+                               url => '',
+                       },
+               ],
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "N",
+                       ksh  => "Y",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "N",
+                       ksh  => "Y",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Aliases",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "Y",
+                       rc   => "Y",
+                       sh   => "Y(1)",
+                       tcsh => "N",
+                       zsh  => "Y",
+               },
+               title   => "Shell functions",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "Y",
+                       rc   => "Y",
+                       sh   => "Y",
+                       tcsh => "N",
+                       zsh  => "Y",
+               },
+               title   => "\"Sensible\" Input/Output redirection",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "F",
+                       ksh  => "Y",
+                       rc   => "F",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Directory stack",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "L",
+                       ksh  => "Y",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Command history",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "L",
+                       ksh  => "Y",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Command line editing",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "L",
+                       ksh  => "Y",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y(3)",
+                       zsh  => "Y",
+               },
+               title   => "Vi Command line editing",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "L",
+                       ksh  => "Y",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Emacs Command line editing",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "L",
+                       ksh  => "N",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Rebindable Command line editing",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "L",
+                       ksh  => "Y",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "User name look up",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "F",
+                       ksh  => "N",
+                       rc   => "F",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Login/Logout watching",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y(1)",
+                       es   => "L",
+                       ksh  => "Y",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Filename completion",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y(2)",
+                       es   => "L",
+                       ksh  => "Y",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Username completion",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y(2)",
+                       es   => "L",
+                       ksh  => "Y",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Hostname completion",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "L",
+                       ksh  => "N",
+                       rc   => "L",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "History completion",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "N",
+                       ksh  => "N",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Fully programmable Completion",
+       },
+       {
+               support => {
+                       bash => "N(4)",
+                       csh  => "N",
+                       es   => "N",
+                       ksh  => "N",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "N(6)",
+                       zsh  => "N(6)",
+               },
+               title   => "Mh Mailbox completion",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "N",
+                       ksh  => "Y",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "Y",
+               },
+               title   => "Co Processes",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "N",
+                       ksh  => "Y",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Builtin artithmetic evaluation",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "N",
+                       ksh  => "Y",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Can follow symbolic links invisibly",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "N",
+                       ksh  => "N",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Periodic command execution",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "Y",
+                       rc   => "Y",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Custom Prompt (easily)",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "N",
+                       ksh  => "N",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "Y",
+               },
+               title   => "Sun Keyboard Hack",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "N",
+                       ksh  => "N",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Spelling Correction",
+       },
+       {
+               support => {
+                       bash => "Y(2)",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "N",
+                       rc   => "Y",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "Y",
+               },
+               title   => "Process Substitution",
+       },
+       {
+               support => {
+                       bash => "sh",
+                       csh  => "csh",
+                       es   => "rc",
+                       ksh  => "sh",
+                       rc   => "rc",
+                       sh   => "sh",
+                       tcsh => "csh",
+                       zsh  => "sh",
+               },
+               title   => "Underlying Syntax",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "N(5)",
+                       rc   => "Y",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Freely Available",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "F",
+                       ksh  => "Y",
+                       rc   => "F",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Checks Mailbox",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "N",
+                       ksh  => "N",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Tty Sanity Checking",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "Y",
+                       rc   => "Y",
+                       sh   => "Y",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Can cope with large argument lists",
+       },
+       {
+               support => {
+                       bash => "Y(7)",
+                       csh  => "Y",
+                       es   => "N",
+                       ksh  => "Y(7)",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Has non-interactive startup file",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "N",
+                       ksh  => "Y(7)",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "Has non-login startup file",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "Y",
+                       ksh  => "N",
+                       rc   => "Y",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "Y",
+               },
+               title   => "Can avoid user startup files",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "N",
+                       ksh  => "Y",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "N",
+               },
+               title   => "Can specify startup file",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "N",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "N",
+               },
+               title   => "Low level command redefinition",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "N",
+                       rc   => "Y",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "N",
+               },
+               title   => "Has anonymous functions",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "Y",
+                       es   => "Y",
+                       ksh  => "Y",
+                       rc   => "Y",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "List Variables",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "Y",
+                       rc   => "Y",
+                       sh   => "Y",
+                       tcsh => "N",
+                       zsh  => "Y",
+               },
+               title   => "Full signal trap handling",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "Y",
+                       es   => "F",
+                       ksh  => "Y",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "Y",
+                       zsh  => "Y",
+               },
+               title   => "File no clobber ability",
+       },
+       {
+               support => {
+                       bash => "Y",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "Y",
+                       rc   => "Y",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "Y",
+               },
+               title   => "Local variables",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "N",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "N",
+               },
+               title   => "Lexically scoped variables",
+       },
+       {
+               support => {
+                       bash => "N",
+                       csh  => "N",
+                       es   => "Y",
+                       ksh  => "N",
+                       rc   => "N",
+                       sh   => "N",
+                       tcsh => "N",
+                       zsh  => "N",
+               },
+               title   => "Exceptions",
+       },
+
+],
+
+}
diff --git a/shell.plp b/shell.plp
new file mode 100644 (file)
index 0000000..85ababa
--- /dev/null
+++ b/shell.plp
@@ -0,0 +1,78 @@
+<(common.inc.plp)><:
+use List::Util qw(sum max first);
+
+Html({
+       title => 'Shell compatibility cheat sheet',
+       version => '1.0',
+       stylesheet => [qw'circus dark mono red light'],
+       data => ['shell.inc.pl'],
+});
+
+say "<h1>Shell compatibility</h1>\n";
+
+my $data = do 'shell.inc.pl' or die $@ || $!;
+my @agents = keys %{ $data->{agents} };
+
+print '<table class="mapped">';
+print '<col>';  # should match first thead row
+printf '<colgroup span="%d">', 1 for @agents;
+say '</colgroup><col>';
+
+my $header = join('',
+       '<tr>',
+       '<th>feature',
+       (map {
+               sprintf('<th>%s', Entity($_->{name}))
+       } @{ $data->{agents} }{@agents}),
+);
+print '<thead>', $header;
+say '</thead>';
+say '<tfoot>', $header;
+
+sub saytitlecol {
+       my ($row) = @_;
+       print '<td>', Entity($row->{title});
+}
+
+my %DSTATS = (
+       Y => 'feature can be done',
+       N => 'feature is not present',
+       F => 'feature can only be done by using the shells function mechanism',
+       L => 'the readline library must be linked into the shell to enable this feature',
+);
+my %CSTATS = (
+       N => 'l1',
+       F => 'l2',
+       L => 'l4',
+       Y => 'l5',
+);
+
+sub saysupportcols {
+       my ($row, $agent) = @_;
+       my $stat = $row->{support}->{$agent};
+       my $title = join(' ',
+               $DSTATS{$stat} // 'unknown support',
+               'in', $agent,
+       );
+       printf('<td class="%s" title="%s">%s',
+               join(' ',
+                       X => $CSTATS{$stat},
+               ),
+               $title,
+               $stat,
+       );
+}
+
+say '<tbody>';
+for my $row (sort {
+       $a->{title} cmp $b->{title}
+} @{ $data->{feature} }) {
+       (my $id = lc $row->{title}) =~ s/\W+/-/g;
+       printf '<tr id="%s">', $id;
+       saytitlecol($row);
+       saysupportcols($row, $_) for @agents;
+       say '</tr>';
+}
+say '</tbody>';
+say '</table>';
+