Re: Road to a readable path
by VinsWorldcom (Parson) on Apr 15, 2009 at 13:37 UTC
|
On Windows, you don't even need Perl to get a readable path:
for %i in ("%path:;=" "%") do @echo %i
Produces this (for my path):
{C} > for %i in ("%path:;=" "%") do @echo %i
"C:\usr\bin"
"C:\Perl\bin"
"C:\WINDOWS\system32"
"C:\WINDOWS"
"C:\WINDOWS\System32\Wbem"
"c:\Program Files\Microsoft SQL Server\90\Tools\binn\"
"C:\Documents and Settings\Administrator\My Documents\bin"
{C} >
UPDATE: Use "set /?" at the command prompt to find out the new options for environment variable substitution (the %path:;=" "%). Basically, I wrap the %PATH% ENV var in double quotes and then replace all the semicolon separators with a double-quote, space, double quote. This effecitely puts double quotes around all the paths (so spaces won't give any troubles) and we use the for loop to list each newly double-quoted string | [reply] [d/l] [select] |
|
$ echo $PATH | tr ':' '\n'
| [reply] [d/l] |
|
| [reply] [d/l] |
|
|
On Windows, you don't even need Perl to get a readable path
Yeah, but you have to do it in a sucky way :p FYI: when you install perl, you also get the "pl2bat" program (it's actually there to support module installation process I believe) to turn your perl programs into *.bat, so that you don't have to write that dumb basic-ish thing to have general purpose commands on you system.
| [reply] |
Re: Road to a readable path
by Tanktalus (Canon) on Apr 15, 2009 at 13:05 UTC
|
perl -MFile::Spec -le 'print for File::Spec->path'
That should work on Windows, Unix, VMS, and anything else File::Spec supports. :-P | [reply] [d/l] |
|
| [reply] [d/l] |
Re: Road to a readable path
by jwkrahn (Monsignor) on Apr 15, 2009 at 11:23 UTC
|
perl -le "use Env q[@PATH]; print for @PATH"
| [reply] [d/l] |
|
C:\>perl -MEnv=@PATH -le "print for @PATH"
C:\WINDOWS\
...
| [reply] [d/l] |
|
C:\>perl -MEnv=@PATH -le print()for@PATH
...
| [reply] [d/l] |
|
Very interesting. I learned two things from that: about the Env module, and using the -l switch to turn print into say. The docs for Env says that $Config::Config{path_sep} is used, so it will handle Windows properly. Looking at the code in Env.pm, I see that split is given two arguments, so trailing nul fields are stripped, which another poster points out is a problem on Unix. Since that is the normal point of using the Env module, perhaps someone should issue a correction? Actually, it will return the nth item as an empty string if asked for, but it will not count it when checking the size, so the loop won't ask for it. It re-splits every time an element is gotten, yuck.
| [reply] [d/l] [select] |
Re: Road to a readable path (unix)
by toolic (Bishop) on Apr 15, 2009 at 13:45 UTC
|
I've had this code for a while, for unix. By default, it prints out PATH, but it can also accept another environment variable name, such as MANPATH or LD_LIBRARY_PATH. The POD explains it all:
$ perldoc hpath
=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. However, the actual variable name m
+ust
be all upper case.
Input need not be the full variable name. However, the abbreviated in
+put
must allow for "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.
=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_PATH
=cut
use strict;
use warnings;
my $name = (@ARGV) ? uc shift : 'PATH';
# If environment variable does not exist, try appending "PATH" to its
+name:
my $path_var = exists $ENV{$name} ? $ENV{$name} : $ENV{$name . 'PATH'}
+;
if (defined $path_var) {
my @list = split /:/, $path_var;
print "$_\n" for @list;
}
| [reply] [d/l] [select] |
|
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. | [reply] [d/l] [select] |
|
| [reply] |
|
| [reply] |
|
| [reply] |
|
The other update to your script didn't add the ,-1 parameter to the end of the split. This is necessary if empty strings are significant.
| [reply] |
Re: Road to a readable path
by JavaFan (Canon) on Apr 15, 2009 at 11:11 UTC
|
I guess the equivalent on Unix would be something like:
perl -E 'say for grep $_, split /:/, $ENV{PATH}'
However, the grep filters out the empty string. And so does the 2-arg split. But empty strings in PATHs under Unix are significant. So, I'd write:
perl -E 'say for split /:/, $ENV{PATH}, -1'
| [reply] [d/l] [select] |
Re: Road to a readable path
by JavaFan (Canon) on Apr 15, 2009 at 13:51 UTC
|
Another way to do it on Unix:
echo $PATH | perl -F: -lanE 'say for @F'
| [reply] [d/l] |
Re: Road to a readable path
by wol (Hermit) on Apr 21, 2009 at 10:39 UTC
|
I had another look at this after all the replies here, and found that perl provides a way to do this without actually using any Perl!
echo %PATH% | perl -073 -p -l012 -e ""
Conclusion: When using perl, using Perl is optional...
--
use JAPH;
print JAPH::asString();
| [reply] [d/l] |
Re: Road to a readable path
by John M. Dlugosz (Monsignor) on May 11, 2009 at 20:28 UTC
|
I needed something similar for INCLUDE a few days ago. I did it off-the-cuff, and used join instead an explicit loop.
So, to save it as something reusable, I'd suggest having it take a parameter that is the variable name. Or perhaps the output of another command. Or...maybe the built-in env variable editing command needs to be able to format it nicely.
—John
| [reply] [d/l] |