Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

file test results not as expected

by navalned (Sexton)
on Nov 21, 2020 at 22:44 UTC ( #11123993=perlquestion: print w/replies, xml ) Need Help??

navalned has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to push all executibles in my $PATH to an array, but doesn't seem to work as expected.

use IO::Dir; my @cmds; my @paths = split /\:/, $ENV{PATH}; foreach my $path (@paths) { tie my %dir, 'IO::Dir', $path; foreach my $file (keys %dir) { if (-f -x $file) { push @cmds, $file; } } undef %dir; } foreach my $cmd (@cmds) { print $cmd . "\n"; }

Here is the output I'm getting:


I guess its kinda cool it found a perl related executable, but I was hoping for more.

Replies are listed 'Best First'.
Re: file test results not as expected
by toolic (Bishop) on Nov 21, 2020 at 23:33 UTC
    You need to use the full path to the file for the file test. Change:
    if (-f -x $file) {
    if (-f -x "$path/$file") {

    This is how I do it: Finding commands in Unix PATH:

    findcmd is a script which searches through the directories in the Unix PATH variable for executable files

      Thats cool and works well. You can try this for a 5 sec improvement at least on my system:

      grep { -x "$path/$_" && !-d _ }

      Saves a lot of stat() calls.

      Thanks for the answer. I think I knew the answer deep in the recesses of my brain but couldn't see it.

Re: file test results not as expected
by Fletch (Chancellor) on Nov 22, 2020 at 03:13 UTC

    Using Path::Tiny

    $ perl -MPath::Tiny -E 'for my $dir ( split(/:/,$ENV{PATH}) ){say for +grep {-f -x $_} path($dir)->children }'

    Also depending on your shell it may already have these cached. For instance ZSH provides a commands hash which maps from the command name to the corresponding file name.

    $ print -l "${(@k)commands}" | sort | tail zipinfo zipnote zipsplit zless zmore znew zprint zsh zsh-5.8 $ print $commands[zsh] /usr/local/bin/zsh

    Edit: Dump the ZSH cache with for i in "${(@onk)commands}" ; { printf "%20s\t%s\n" "$i" "$commands[$i]" } | less; of course keep in mind that the commands parameter shows only what would be found first on PATH; if you're looking for exhaustive (including things with matching names shadowed in subsequent directories) you'd want the other solutions.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11123993]
Approved by toolic
Front-paged by toolic
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2022-01-19 15:12 GMT
Find Nodes?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:

    Results (55 votes). Check out past polls.