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

Greetings Monks, while using any of the follow* options of the find() command, i'm getting either a 'die' with indications of multiple usage of the same directory under different symlinks or skipping without processing. how could i avoid this behavior? i'm not interested in performance and i don't care about the duplications, i just need the find () command to process all symlinks. thanks, Yaron.

  • Comment on find () command does not process all symlinks

Replies are listed 'Best First'.
Re: find () command does not process all symlinks
by eyepopslikeamosquito (Archbishop) on Apr 26, 2024 at 09:01 UTC

    This looks like a continuation of your first post : how to use find() options. If so, you should have indicated that.

    You seem to have ignored my friendly advice in that thread to create a SSCCE, so I'll try to make it clearer what we want to see from you in future posts: Show me the code! :-)

    👁️🍾👍🦟
      > This looks like a continuation of your first post

      Well spotted, Golden Eye! ;)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery

Re: find () command does not process all symlinks
by hippo (Archbishop) on Apr 26, 2024 at 08:00 UTC

    There is no find() function in Perl so you are probably referring to a facility provided by a module but have forgotten to specify which one. Please consider providing an SSCCE to help us to help you.


    🦛

      Hi Hippo (and other generous Monks...), it is a continuation of my previous request. i am attaching an example. please note that i tried changing the 'follow' option with 'follow_fast' which did not help or 'follow_skip' which offers only die or ignore possibilities that does not fit me. thanks, Yaron.

      use File::Find; find({wanted => \&search_tcl_files, follow => 1},$directory);

        I am sure that when you re-read the code which you have presented here you will realise at once that it is not an SSCCE. That is a shame for you because the problem (if indeed there actually is one) is in the code which you have chosen not to show us.

        Here is the sort of thing which you should have provided. Note that this demonstrates that the syntax in the 2 lines which you have shown works perfectly well.

        #!/usr/bin/env perl use strict; use warnings; use File::Find; use Path::Tiny; # Construct the tree my $dir = path('quux'); my $file = $dir->child('baz')->touchpath; link $file, $dir->child($_) for qw/foo bar/; # Run the iterator find ({wanted => sub { print "found $_\n" }, follow => 1}, $dir); # Clean up $dir->remove_tree;

        🦛

        This does not qualify as an example. What "example" means is code that we can independently run and see your problem on our machines.

        From Perl Doc - File::Find:
        follow_skip
        follow_skip==1, which is the default, causes all files which are neither directories nor symbolic links to be ignored if they are about to be processed a second time. If a directory or a symbolic link are about to be processed a second time, File::Find dies.

        follow_skip==2 causes File::Find to ignore any duplicate files and directories but to proceed normally otherwise.

        So, this looks worth a try:

        find({wanted => \&search_tcl_files, follow => 1, follow_skip=>2},$dire +ctory);
Re: find () command does not process all symlinks
by LanX (Saint) on Apr 26, 2024 at 08:42 UTC
    Are you referring to File::Find ?

    As hippo already said, you should give us more informations to replicate your problem - an SSCCE - otherwise we need to guess

    • your OS
    • set of directories with symlinks
    • the code you used, minimized to the essential
    • the desired outcome
    • the result you got

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

Re: find () command does not process all symlinks
by tybalt89 (Monsignor) on Apr 27, 2024 at 16:25 UTC

    My guess is that File::Find vigorously protects you from doing what you want.

    After closely inspecting your non-existent SSCCE and taking an enormous leap of intuition, here's an SSCCE with a couple of choices for what I think your non-existent SSCCE shows you want :)

    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11159091 use warnings; use Path::Tiny; my $dir = path('a'); $dir->remove_tree; path('a/b/c')->mkdir; path('a/b/c/file.tcl')->touch; symlink 'b', 'a/sym1'; symlink 'c', 'a/b/sym2'; system 'echo from the system tree command to show file structure;tree' +; print "\n"; my @folders = 'a'; # FIXME set to base of folder(s) while( my $path = shift @folders ) { push @folders, grep -d, <$path/*>; print "$0: $_\n" for <$path/*.tcl>; } print "\n"; path('a')->visit(sub{/\.tcl$/ and print "Path::Tiny::visit: $_\n"}, {recurse => 1, follow_symlinks => 1} ); print "\n"; use File::Find; find ({wanted => sub {/\.tcl$/ and print "File::Find $File::Find::name +\n" }, follow_skip => 2 }, 'a');

    which outputs:

    from the system tree command to show file structure . `-- a |-- b | |-- c | | `-- file.tcl | `-- sym2 -> c `-- sym1 -> b 6 directories, 1 file ../2perltree.pl: a/b/c/file.tcl ../2perltree.pl: a/b/sym2/file.tcl ../2perltree.pl: a/sym1/c/file.tcl ../2perltree.pl: a/sym1/sym2/file.tcl Path::Tiny::visit: a/sym1/c/file.tcl Path::Tiny::visit: a/sym1/sym2/file.tcl Path::Tiny::visit: a/b/c/file.tcl Path::Tiny::visit: a/b/sym2/file.tcl File::Find a/b/c/file.tcl

    This output was generated on an ArchLinux system. It's possible that Find::File for the OS on your (unspecified) system (OS/2 BSD4.2 RSX-11M MVS Multics etc) may behave differently.