http://qs321.pair.com?node_id=11130749

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

Trying to pull a list of C++ files from a fixed project directory. The system command shows a list of files verifying that the directory is correct. Find::File::Rule returns an empty list. I've tried many versions of the command block and I'm out of ideas at this point. This has to be a duh moment. What have I missed?

File::Find::Rule is up to date on my install.

I will add a grep section later to pull #include statements out of the files.

Thanks!

#! /usr/bin/perl use strict; use warnings; use File::Find::Rule; use Data::Dumper; my $dir = ('~/Hamradio/Keithsdr/KEITHSDR-main/SDR_RA8875/'); system "ls $dir"; # This works and verifies the search # path - $dir my @files = File::Find::Rule->file() ->name('*.cpp') ->in($dir); print Dumper $dir; # Good directory string # $VAR1 = '~/Hamradio/Keithsdr/ # KEITHSDR-main/SDR_RA8875/'; print Dumper(\@files); # Empty list $VAR1 = []

James

There's never enough time to do it right, but always enough time to do it over...

Replies are listed 'Best First'.
Re: File::Find::Rule Help Needed
by huck (Prior) on Apr 02, 2021 at 23:23 UTC
    try
    my $dir = ($ENV{HOME}.'/Hamradio/Keithsdr/KEITHSDR-main/SDR_RA8875/');
    Perl doesnt know ~
      An alternative to $ENV{HOME} is (getpwuid $>)[7]. I don't know which might be better, if one is. If you're in a shell environment and $HOME either doesn't exist or is stripped, then that could be an issue. For example, I do this a lot:

      my $HOME = (getpwuid $>)[7]; my $ssh_dir = qq{$HOME/.ssh};

      (update)
      I wanted to add, that getpwuid is probably more reliable when you're doing stuff with setuid; in the example above, $> is the effective user; $< being the real user. I don't think invoking it updates $ENV in any way, like su - OTHER_USER would directly in the shell before invoking the script in question (certainly doing this in the script would not effect the parent process's %ENV at all). perlsec looks informative regarding this. But it just depends on what OP is doing. If there is no reason or need to use setuid (or setguid), then $ENV{HOME} is probably fine.

      Huck:

      That did the trick! I would never have stumbled onto that. Hopefully I will remember that next time. Now onto the grep section.

      Thank you very much!

      Update: I have no excuse. If I would have consulted my copy of the Perl Cookbook I would have found a recipe in chapter 7 that addressed this issue. File list created and files searched for #includes. Done...

      #! /usr/bin/perl # Keithsdr.pl - Script to search for the libraries used by the # C++ source files of the KeithSDR project. # Output to assist with creating documentation. # # James M. Lynes Jr. - KE4MIQ # Created: April 3, 2021 # Last Modified: 4/03/2021 - First working version # use strict; use warnings; use File::Find::Rule; use Data::Dumper; my $input; my $output; open ($output, ">", "keithsdrdoc"); my $dir = ($ENV{HOME}.'/Hamradio/Keithsdr/KEITHSDR-main/SDR_RA8875/'); # # Create a list of C++ files from the SDR_RA8875 directory # my @files = File::Find::Rule->file() ->name('*.cpp', '*.ino') ->maxdepth(1) ->start($dir) ->in($dir); # # Sort the file list # my @sorted = sort @files; @files = @sorted; # # Search each C++ file for library files(#include) # foreach my $file (@files) { print "$file\n"; print $output "$file\n"; open ($input, "<", $file) or die; while (<$input>) { chomp(); if (/#include/) { print "$_\n"; print $output "$_\n"; } } print "\n"; print $output "\n"; } close($input); close($output);

      James

      There's never enough time to do it right, but always enough time to do it over...