in reply to
Re: Road to a readable path (unix)
in thread Road to a readable path
That's really neat in that it encourages laziness. The only downside is that so many variables use "_PATH" at the end that it seems silly that I have to type "hpath ld_library_" - it's the underscores that are the painful part to my sense of laziness ;-) So, I have two solutions for you. First is to allow "_PATH" as well as "PATH" as suffixes. The second is to allow "-" as a "lower case" version of "_". The other downside is that limitation on the env vars being uppercase names. So I eliminated that, too (more or less).
#!/usr/bin/perl
=head1 NAME
B<hpath> - Human-readable print of Unix PATH variable
=head1 SYNOPSIS
hpath [name]
Options:
name Name of an environment variable
=head1 DESCRIPTION
Prints each item of a path-type environment variable onto its own line
+.
Useful for displaying PATH variable, for example. A path-type variabl
+e
is really any variable which is a colon-separated list.
Takes as input an environment variable name.
Input need not be all upper case.
Input need not be the full variable name. However, the abbreviated in
+put
must allow for "PATH" or "_PATH" to be appended to it.
For example, "man", "MAN", "manpath" and "MANPATH" will all resolve to
"MANPATH".
If no input is given, the default is "PATH".
Output is STDOUT.
To promote laziness, -'s will be converted to _'s. This allows you
to use "ld-library" to print out LD_LIBRARY_PATH.
=head1 EXAMPLES
Print the value of the PATH environment variable, one directory per li
+ne:
hpath
Print the value of the MANPATH environment variable:
hpath man
Print the value of the LD_LIBRARY_PATH environment variable:
hpath ld-library
=cut
use strict;
use warnings;
my $name = (@ARGV) ? uc shift : 'PATH';
# If environment variable does not exist, try appending "PATH" to its
+name:
my @attempts = ($name, "${name}PATH", "${name}_PATH");
# If that still won't work, try converting -'s to _'s
if ($name =~ /-/)
{
push @attempts, map { (my $n = $_) =~ s/-/_/g; $n } @attempts;
}
my $path_var;
for (@attempts)
{
if (exists $ENV{$_})
{
$path_var = $ENV{$_};
last;
}
}
# if THAT still doesn't work, try case-insensitively.
if (not defined $path_var)
{
for my $a (@attempts)
{
my @matches = grep { lc $a eq lc } keys %ENV;
if (@matches == 1)
{
$path_var = $ENV{$matches[0]};
last;
}
elsif (@matches > 1)
{
# err... which one? Probably should check if one
# matches the input exactly, but we'll leave that as
# an excersise for the reader :-)
last;
}
}
}
if (defined $path_var) {
my @list = split /:/, $path_var;
print "$_\n" for @list;
}
It probably should print "No such env var found" to STDERR if nothing is found, too, but that's a matter of opinion.
The neat thing here is how much more convenient it is to script something based on the list of directories when they're separated by whitespace, or even newlines, than colons. For example, hpath foo | while read thisfoo; do : stuff ; done Yes, it's possible to do with tr, as above, but with a bunch of smarts in the perl code, you could take a flag from the user for which env var to look at: hpath $1 | while read thisone; do : stuff; done and have the flexibility to allow for shortcuts way easier than pure shell.