Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Re: File::Find and remove invalid symlinks question

by Eily (Monsignor)
on Jul 21, 2020 at 15:53 UTC ( #11119610=note: print w/replies, xml ) Need Help??

in reply to File::Find and remove invalid symlinks question

They give different results when I test them on a debian with perl v5.28. I have link2 -> link1 and link1 -> my_file (where my_file doesn't exist). The first version only returns link1, while the second also includes link2.

With a dangling link "a link whose target does not exist", whether the first result is expected depends on your definition of "exist" :)

  • Comment on Re: File::Find and remove invalid symlinks question

Replies are listed 'Best First'.
Re^2: File::Find and remove invalid symlinks question
by perlfan (Vicar) on Jul 21, 2020 at 16:41 UTC
    From File::Find:
    * dangling_symlinks
    Specifies what to do with symbolic links whose target doesn't exist. If true and a code reference,
    will be called with the symbolic link name and the directory it lives in as arguments. Otherwise,
    if true and warnings are on, a warning of the form "symbolic_link_name is a dangling symbolic link\n"
    will be issued. If false, the dangling symbolic link will be silently ignored.

    And stat/lstat (WP):

    The stat() and lstat() functions take a filename argument. If the file is a symbolic link,
    stat() returns attributes of the eventual target of the link, while lstat() returns attributes
    of the link itself. The fstat() function takes a file descriptor argument instead, and returns
    attributes of the file that it identifies.
    Note: Perl docs - stat, lstat

    It seems that the question that needs to be answered is, is dangling_symlinks invoked for conditions equivalent to -l && !-e on the file is true?

    From what I dug up while getting the above clarifications, it seems that there are great pains in both documents (and elsewhere) that differentiate the link itself and the file that is the target of the link. So make sure you're being consistent in what you're testing and that you are recreating the identical conditions for which dangling_symlinks is invoked.

    Another thought occurred to me that there could be some interactions in

    sub{if (-l && !-e){

    Since you're testing $_ (I assume) when you might want (or not) to do something like sub{if (-l && !-e _){, which is going to avoid calling stat or lstat again. Not super solid on this nuance, but just saying to verify it's doing what you expect.

    Update (from From -X):

    If any of the file tests (or either the stat or lstat operator) is given the special filehandle consisting of
    a solitary underline, then the stat structure of the previous file test (or stat operator) is used, saving a
    system call. (This doesn't work with -t , and you need to remember that lstat and -l leave values in the stat
    structure for the symbolic link, not the real file.) (Also, if the stat buffer was filled by an lstat call,
    -T and -B will reset it with the results of stat _ ).

    So there you go...hopefully clear as mud now. :)

      Thanks for all the replies

      I think the difference between 1 and 2 is the behaviour when the link target is itself a symlink, for my use case this doesn't matter, because there will not be any links to links

      Adding _ to if (-l && !-e) makes the script return zero records. I belive this is because File::Find already does this, so it is in essence (-l $_ && !-e __)

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11119610]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (1)
As of 2023-03-31 02:30 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (74 votes). Check out past polls.