bugfindutils - Bugs: bug #56410, find -L doesn't follow symlinks...

 
 

bug #56410: find -L doesn't follow symlinks outside the specified search scope

Submitter:  None
Submitted:  Wed 29 May 2019 07:49:18 AM UTC
   
 
Category:  find Severity:  3 - Normal
Item Group:  Wrong result Status:  Working as Intended
Privacy:  Public Assigned to:  jay
Originator Name:  Arthur Pogosyan Originator Email:  -email is unavailable-
Open/Closed:  Open Release:  None
Fixed Release:  4.7.0
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Mon 17 Jun 2019 09:59:12 PM UTC, comment #17: 

Maybe similar to what GNU coreutils' ls?

https://www.gnu.org/software/coreutils/ls


‘-L’
‘--dereference’

    When showing file information for a symbolic link, show information for the file
    the link references rather than the link itself. However, even with this option,
    ls still prints the name of the link itself, not the name of the file that the
    link points to.


Obviously, this has to be extended for find(1) because also the
tests like -size act on the de-referenced file (if it is a resolvable file).



Bernhard Voelker <berny>
Group administrator
Thu 13 Jun 2019 11:05:15 PM UTC, comment #16: 

Yes, I think we should fix the description of -L.   Thanks, Andreas.

Incidentally our interpretation of {} is consistent with that in, for example, Solaris:

$ find -L . -ls -print -exec echo {} \;
176544    2 drwxr-xr-x   2 james    other           4 Jun 13 23:56 .
.
.
176545    1 -rw-r--r--   1 james    other           6 Jun 14 00:02 ./b
./b
./b
176545    1 -rw-r--r--   1 james    other           6 Jun 14 00:02 ./a
./a
./a

James Youngman <jay>
Group administrator
Wed 05 Jun 2019 05:29:38 PM UTC, comment #15: 

Bernhard Voelker wrote:

> I'm trying to find the documentation which would make you as a our user think that -L would let -print or "-exec ... {}' +" use the resolved path name.



I think the description of -L very clearly states this:

-L     Follow symbolic links.  When find examines or prints information about files, [...]

The filename is "information about files". The real behavior of -L is more complicated than what this sentence says.

Andreas Metzler <ametzler>
Wed 05 Jun 2019 06:22:18 AM UTC, comment #14: 

We're always interested in improving things, so thanks again for reporting
an issue like this.

The implementation of -L is correct - or at least we don't have a proven
example where it wouldn't be -; (only) the search, i.e., the tests, are based
on the file referenced by the file a symbolic link points to.
Or in the words of POSIX:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/find.html

Cause the file information and file type evaluated for each symbolic link encountered
as a path operand on the command line or encountered during the traversal of a file
hierarchy to be those of the file referenced by the link, and not the link itself.


I'm trying to find the documentation which would make you as a our user
think that -L would let -print or "-exec ... {}' +" use the resolved path name.
Would you point us to such unclear passage, or even better provide a clearer
phrasing as a matter for discussion?

Thanks & have a nice day,
Berny


Bernhard Voelker <berny>
Group administrator
Wed 05 Jun 2019 05:37:02 AM UTC, comment #13: 

OK. This is your product, and you can do with it whatever you want(or don't do). But the manual doesn't describe correct beahviour of -L option. I'm not developer, i'm just a user. And from user's point of view this option works wrong

Arthur Pogosyan <xqzts>
Tue 04 Jun 2019 10:16:22 PM UTC, comment #12: 

The information is a bit spread in the documentation.
There is:


‘-print’
‘-fprint’
  [...] is handled in the same way as for the ‘%p’ directive of
  ‘-printf’ and ‘-fprintf’.


and:


%p
  File’s name (not the absolute path name, but the name of the
  file as it was encountered by find - that is, as a relative
  path from one of the starting points).


Is that sufficient?

Bernhard Voelker <berny>
Group administrator
Tue 04 Jun 2019 05:45:09 AM UTC, comment #11: 

Thank's for workaround, Berny!
BUT!
The key point of this option according to manual:
When find examines or prints information about files, the information used shall be taken from the properties of the file to which the link points, not from the
link itself

Many of my coleagues read manual of find, and understood it just like me. And were surprised by current find behaviour. I mean, why do you need this option if "GNU find will always pass the original name of the file found, regardless whether -L is in
place or not"?

At my point of view, change is needed. Either in manual page of find or in its behaviour.

Thanks again for workaround!

Arthur Pogosyan <xqzts>
Sat 01 Jun 2019 05:32:34 PM UTC, comment #10: 

While find(1) act on the de-referenced file with -L, the called file(1) does not - per default.  GNU find will always pass the original name of the file found, regardless whether -L is in
place or not.  I think you simply want also file(1) to work on
the de-referenced file, so this can easily be done by passing
the -L option to file(1).

  $ find -L ... -exec file -L '{}' +

Have a nice day,
Berny

Bernhard Voelker <berny>
Group administrator
Thu 30 May 2019 09:28:09 AM UTC, comment #9: 

OK, i'm trying to say, that according to find manual page:

---
 -L     Follow symbolic links.  When find examines or prints information about files, the information used shall be taken from the properties of the file to which the link points,  not  from  the
              link  itself  (unless  it  is a broken symbolic link or find is unable to examine the file to which the link points).  Use of this option implies -noleaf.  If you later use the -P option,
              -noleaf will still be in effect.  If -L is in effect and find discovers a symbolic link to a subdirectory during its search, the subdirectory pointed to  by  the  symbolic  link  will  be
              searched.
---

after executing "find -L temp2/ -type f" we should receive following output:
temp/file0.txt

As i think after reading manual find should follow symlink and give me info about text file, but not symlink itself.

Arthur Pogosyan <xqzts>
Thu 30 May 2019 09:03:42 AM UTC, comment #8: 


> So that i didn't do anything with found files and not using {}. But still with -L option it shows me symlink instead of text file.


I don't understand what you are trying to say there.   What part of the output of your script do you think is wrong?   What output did you expect instead?

James Youngman <jay>
Group administrator
Thu 30 May 2019 06:56:00 AM UTC, comment #7: 

I've modified your script a little:

#!/bin/bash
set -u
if ! top="$(mktemp -d)"; then echo "Failed to create a temporary directory" >&2; exit 1; fi
(
set -eCu
cd "${top}"
mkdir temp temp2
echo "test" >| temp/file0.txt
( cd temp2 && ln -s ../temp/file0.txt file )
if ! wc -c < temp2/file >/dev/null ; then exit 1; fi
echo
echo with -L
find -L temp2/ -type f
echo "(ends)"
echo
echo without -L
find temp2/ -type f
echo "(ends)"
echo
echo with -L ... -exec file
find -L temp2/ -type f -exec file '{}' \;
echo "(ends)"
echo
)
rv=$?
ls -ltR "${top}"
rm -rf "${top}"
exit $rv

So that i didn't do anything with found files and not using {}. But still with -L option it shows me symlink instead of text file.
Here's output script produced:

root@ubuntu1804x64:~# bash test.sh

with -L
temp2/file
(ends)

without -L
(ends)

with -L ... -exec file
temp2/file: symbolic link to ../temp/file0.txt
(ends)

/tmp/tmp.ap8ae5weXs:
total 8
drwxr-xr-x 2 root root 4096 May 30 09:52 temp
drwxr-xr-x 2 root root 4096 May 30 09:52 temp2

/tmp/tmp.ap8ae5weXs/temp:
total 4
-rw-r--r-- 1 root root 5 May 30 09:52 file0.txt

/tmp/tmp.ap8ae5weXs/temp2:
total 0
lrwxrwxrwx 1 root root 17 May 30 09:52 file -> ../temp/file0.txt

Arthur Pogosyan <xqzts>
Wed 29 May 2019 05:38:08 PM UTC, comment #6: 

No, {} always expands to the file being considered, whether or not file properties are examined with stat (find -L) or lstat (find -P).  This mostly makes a difference for the final file name component, since find follows directory symlinks when descending through the file system.

James Youngman <jay>
Group administrator
Wed 29 May 2019 10:55:52 AM UTC, comment #5: 

Correct me if i'm wrong, but with -L you should receive temp/file0.txt, not temp2/file.

Arthur Pogosyan <xqzts>
Wed 29 May 2019 10:43:17 AM UTC, comment #4: 

The output I get looks like this:

$ sh sv56410.sh

with -L
  3152508      4 -rw-r--r--   1 youngman primarygroup        5 May 29 11:41 temp2/file
(ends)

without -L
(ends)

with -L ... -exec file
temp2/file: symbolic link to ../temp/file0.txt
(ends)

/tmp/tmp.jbIJfW8mse:
total 8
drwxr-xr-x 2 youngman primarygroup 4096 May 29 11:41 temp
drwxr-xr-x 2 youngman primarygroup 4096 May 29 11:41 temp2

/tmp/tmp.jbIJfW8mse/temp:
total 4
-rw-r--r-- 1 youngman primarygroup 5 May 29 11:41 file0.txt

/tmp/tmp.jbIJfW8mse/temp2:
total 0
lrwxrwxrwx 1 youngman primarygroup 17 May 29 11:41 file -> ../temp/file0.txt

James Youngman <jay>
Group administrator
Wed 29 May 2019 10:42:22 AM UTC, comment #3: 

Oops, here is a corrected script (the previous one had a missing "!" in the if. 

#!/bin/bash

set -u

if ! top="$(mktemp -d)"; then echo "Failed to create a temporary directory" >&2; exit 1; fi

(
set -eCu
cd "${top}"
mkdir temp temp2
echo "test" >| temp/file0.txt
( cd temp2 && ln -s ../temp/file0.txt file )
if ! wc -c < temp2/file >/dev/null ; then exit 1; fi
echo
echo with -L
find -L temp2/ -type f -ls
echo "(ends)"
echo
echo without -L
find  temp2/ -type f -ls
echo "(ends)"
echo
echo with -L ... -exec file
find -L temp2/ -type f -exec file '{}' \;
echo "(ends)"
echo
)
rv=$?
ls -ltR "${top}"
rm -rf "${top}"
exit $rv

James Youngman <jay>
Group administrator
Wed 29 May 2019 10:36:43 AM UTC, comment #2: 

The -L option affects the way that "find" treats symbolic links.  But it has no effect on the "file" program run by -exec.   {} expands to the file that "find" is currently considering, which is in this case is a symbolic link.   Tests made by find on properties will reflect the properties of the file pointed to by find, but {} will expand to the name of the symbolic link (and not its target).

Here is a shell script which I think demonstrates the point you were trying to make, but without requiring root privileges.

#!/bin/bash

set -u

if ! top="$(mktemp -d)"; then
  echo "Failed to create a temporary directory" >&2
  exit 1
fi

(
set -eCux
cd "${top}"
mkdir temp temp2
echo "test" >| temp/file0.txt
( cd temp2 && ln -s ../temp/file0.txt file )
if wc -c < temp2/file >/dev/null ; then
  exit 1
fi
find -L temp2/ -type f -exec file '{}' \;
)
rv=$?
ls -ltR "${top}"
rm -rf "${top}"
exit $rv

James Youngman <jay>
Group administrator
Wed 29 May 2019 10:20:06 AM UTC, comment #1: 

Please provide a specific example, including detailed setup instructions, that reproduces your problem.

James Youngman <jay>
Group administrator
Wed 29 May 2019 07:49:18 AM UTC, original submission:  

Hello!

I was trying to find files from directory full of symlinks and exec file on them, but wasn't able to do so. Find just show info about symlinks, instead of files they lead to, despite option -L was specified

Here is an example:

root@ubuntu1804x64:~# find --version
find (GNU findutils) 4.7.0-git
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Eric B. Decker, James Youngman, and Kevin Dalley.
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2)
root@ubuntu1804x64:~# mkdir /temp
root@ubuntu1804x64:~# mkdir /temp2
root@ubuntu1804x64:~# echo "test" > /temp/file0.txt
root@ubuntu1804x64:~# ln -s /temp/file0.txt /temp2/file
root@ubuntu1804x64:~# find -L /temp2/ -type f -exec file '{}' \;
/temp2/file: symbolic link to /temp/file0.txt

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by berny (Posted a comment)
  • -email is unavailable- added by xqzts (Posted a comment)
  • -email is unavailable- added by jay (Posted a comment)
  • -email is unavailable- added by None (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2019-05-29 jay StatusNeed Info Working as Intended
    2019-05-29 jay StatusNone Need Info
        Assigned toNone jay

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code