Bug 650787 - Inconsistency of physical / logical directory structure and tab completion
Summary: Inconsistency of physical / logical directory structure and tab completion
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Fedora
Classification: Fedora
Component: bash
Version: 14
Hardware: Unspecified
OS: Linux
low
medium
Target Milestone: ---
Assignee: Roman Rakus
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-11-08 03:50 UTC by James
Modified: 2014-01-13 00:13 UTC (History)
6 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2012-08-16 22:16:06 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description James 2010-11-08 03:50:24 UTC
Description of problem:
When current path is in a soft linked folder, bash seems to consider relative path from the absolute path of the target folder instead of the current folder.

Version-Release number of selected component (if applicable):
8.5

How reproducible:


Steps to Reproduce:
1. cd to any empty folder
2. mkdir folderA folderB folderA/folderC
3. ln -s folderA/folderC
4. touch folderC/file
5. cd folderC
6. cp folderC ../folderB
  
Actual results:
folderC/file copied to a file with path and name folderA/folderB

Expected results:
folderC/file copied to folderB

Additional info:
If I change cp to mv. It produces the similar result.

I don't know if the result is really expected by developers. But when I type the commands above, I really mean to copy file to folderB.

Thank you!

Comment 1 Kamil Dudka 2010-11-08 08:11:10 UTC
I am not able to execute your steps to to reproduce.  Did you mistype something?

$ mkdir folderA folderB folderA/folderC
$ ln -s folderA/folderC
$ touch folderC/file
$ cd folderC
$ cp folderC ../folderB
cp: cannot stat `folderC': No such file or directory

$ cd ..
$ tree
.
├── folderA
│   └── folderC
│       └── file
├── folderB
└── folderC -> folderA/folderC

Either way I don't see any problem with coretuils here.  If you think there is a problem with bash, please append also the version of bash.

Comment 2 James 2010-11-08 08:18:28 UTC
(In reply to comment #1)
> I am not able to execute your steps to to reproduce.  Did you mistype
> something?
> 
> $ mkdir folderA folderB folderA/folderC
> $ ln -s folderA/folderC
> $ touch folderC/file
> $ cd folderC
> $ cp folderC ../folderB
> cp: cannot stat `folderC': No such file or directory
> 
> $ cd ..
> $ tree
> .
> ├── folderA
> │   └── folderC
> │       └── file
> ├── folderB
> └── folderC -> folderA/folderC
> 
> Either way I don't see any problem with coretuils here.  If you think there is
> a problem with bash, please append also the version of bash.

I'm very sorry. I mistyped the last step. It should be:
cp file ../folderB

Really sorry for my mistake.

Comment 3 Ondrej Vasik 2010-11-08 12:54:50 UTC
Thanks for report. At least there is a inconsistency in how GNU coreutils pwd and Bash builtin pwd behaves by default in the case of symlinks. GNU coreutils tries to avoid symlinks in pwd unless POSIXLY_CORRECT variable is specified.

[Reset@localhost folderC]$ echo $PWD                                          
/home/Reset/tmp/symlink/folderC

[Reset@localhost folderC]$ pwd                                          
/home/Reset/tmp/symlink/folderC

[Reset@localhost folderC]$ /bin/pwd -L
/home/Reset/tmp/symlink/folderC

[Reset@localhost folderC]$ POSIXLY_CORRECT=yes /bin/pwd
/home/Reset/tmp/symlink/folderC

[Reset@localhost folderC]$ /bin/pwd
/home/Reset/tmp/symlink/folderA/folderC

--------------------------------------
Similar:
[Reset@localhost symlink]$ ls                                                   
folderA  folderB  folderC

[Reset@localhost symlink]$ cd folderC                                           

[Reset@localhost folderC]$ ls ../                                               
folderC

I don't see how to disable this automatic avoiding symlink source (and using physical source location) in the case of ls/mv/cp utilities. But probably it is at least worth of mentioning in info documentation.

Comment 4 Kamil Dudka 2010-11-08 14:19:10 UTC
(In reply to comment #3)
> [Reset@localhost folderC]$ echo $PWD                                          
> /home/Reset/tmp/symlink/folderC

I agree most shells behave this way, but POSIX [1] says something different IMO:

PWD
    Set by the shell to be an absolute pathname of the current working directory, containing no components of type symbolic link, no components that are dot, and no components that are dot-dot when the shell is initialized. If an application sets or unsets the value of PWD , the behaviors of the cd and pwd utilities are unspecified.

> I don't see how to disable this automatic avoiding symlink source (and using
> physical source location) in the case of ls/mv/cp utilities. But probably it is
> at least worth of mentioning in info documentation.

getcwd() knows nothing about symlinks.  So the only way to get the info, is the shell variable $PWD, which is far beyond our control.  It can/should be done at user's level I think -- something like:

$ cp file `dirname $PWD`/folderB

I am not sure where is the right place to mention it...

[1] http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html

Comment 5 Ondrej Vasik 2010-11-09 14:04:20 UTC
Ok ... 
BASH(1) manpage , cd section says:
The  -P option  says  to use the physical directory structure instead of following symbolic links (see also the  -P  option  to  the  set builtin command); the -L option forces symbolic links to be followed.

From the /home/Reset/tmp/symlink/ directory you could use:

[Reset@localhost symlink]$ cd -P folderC
[Reset@localhost folderC]$ echo $PWD
/home/Reset/tmp/symlink/folderA/folderC

[Reset@localhost symlink]$ cd -L folderC                                       
[Reset@localhost folderC]$ echo $PWD
/home/Reset/tmp/symlink/folderC

cd -L is default - and this fact is probably the only missing thing to document. Reassigning to bash. Roman, feel free to close this NOTABUG, if you think that the default behaviour of cd in the case of symlinks is documented enough.

Comment 6 Roman Rakus 2010-11-09 14:58:01 UTC
(In reply to comment #5)
> Ok ... 
> BASH(1) manpage , cd section says:
Here it comes:
> The  -P option  says  to use the physical directory structure instead of
> following symbolic links
It's saying all.

Comment 7 Ondrej Vasik 2010-11-09 15:05:32 UTC
Yep, but it doesn't say anything about defaults... ;)

Comment 8 Roman Rakus 2010-11-09 15:22:41 UTC
(In reply to comment #7)
> Yep, but it doesn't say anything about defaults... ;)

ok, if you are looking for the word `default', look at -P option to the builtin command. `cd' builtin points there.

Comment 9 Kamil Dudka 2010-11-09 15:35:30 UTC
(In reply to comment #8)
> look at -P option to the builtin command.

s/builtin/set builtin/

Comment 10 Ondrej Vasik 2010-11-09 15:56:44 UTC
(In reply to comment #8)
> ok, if you are looking for the word `default', look at -P option to the builtin
> command. `cd' builtin points there.

Ah, you are right (in fact it is hard to find anyway, as there are more columns describing other -P options ;) ) :

-P     If set, the shell does not follow  symbolic  links  when executing  commands  such  as cd that change the current working  directory.   It  uses  the  physical  directory structure instead.  By default, bash follows the logical chain of  directories  when  performing  commands  which change the current directory.

That is clear enough. However RHCBDR (Red Hat Certified Bash Documentation Reader) certification needed to find it :) ...

Comment 11 James 2010-11-10 03:09:49 UTC
Well, don't you think this is not only a documentation problem?

As Ondrej Vasik said, there is an inconsistency between two pwd commands. Bash let user think that symlinks work as normal directories. But coreutils handles it differently. I think the bash method is more convenient to user, do you? Why not make the default action of two pwds uniform?

Comment 12 Kamil Dudka 2010-11-10 08:11:58 UTC
The default behavior simply can't be changed without breaking bunch of already existing (and working) scripts.  And I don't think that one default behavior is more correct than the other one.  It's just a matter of personal preference.

You are free to switch the default behavior locally by 'set -P', 'alias', etc.

I should also note that bash is not the only implementation of shell.  Even in Fedora we provide a few other shells, which may have different default behavior.

Comment 13 James 2010-11-10 08:19:51 UTC
(In reply to comment #12)
> The default behavior simply can't be changed without breaking bunch of already
> existing (and working) scripts.  And I don't think that one default behavior is
> more correct than the other one.  It's just a matter of personal preference.
> 
> You are free to switch the default behavior locally by 'set -P', 'alias', etc.
> 
> I should also note that bash is not the only implementation of shell.  Even in
> Fedora we provide a few other shells, which may have different default
> behavior.

Thank you for your reply. Am I able to set the default behavior of coreutils to that of bash? I prefer following symlinks. Thank you!

Comment 14 Kamil Dudka 2010-11-10 08:38:06 UTC
I am not sure what you mean by 'behavior of coreutils'.

If the question is about 'pwd', then just use 'pwd -L'.  But I am pretty sure you are using the 'pwd' builtin from bash unless you specify something like /bin/pwd.

If the question is about 'cd', there is no equivalent utility in coreutils.

Comment 15 James 2010-11-10 08:56:21 UTC
I am sorry for my confusing words.

In my example above, if I'm in 'test/folderC/', I want to let ls/cp/mv to consider '../' as 'test/' rather than 'test/folderA/'. Is there any way to do this?

Thank you!

Comment 16 Kamil Dudka 2010-11-10 09:08:31 UTC
(In reply to comment #15)
> In my example above, if I'm in 'test/folderC/', I want to let ls/cp/mv to
> consider '../' as 'test/' rather than 'test/folderA/'. Is there any way to do
> this?

That's, however, nothing specific to coreutils.  This way just operating systems work.  Current working directory (CWD) is kept as dev/ino pair on Linux, no symlinks.  Relative paths are then resolved relatively to that CWD in vast majority of syscalls, no matter what your shell tells you.

There is no point in hacking ls/cp/mv, because you will encounter the same problem with grep, findutils, sendmail, etc.  You would end up by rewriting your kernel ;-)

Comment 17 James 2010-11-10 09:37:38 UTC
Oh, I see. Thank you very much!

But I think there is still a way without hacking ls/cp/mv or even kernel:
to let bash perform filename expansion on '..'.
Is that right?

By the way, I found a strange thing.

If I'm in test/folderC/, type in '../folder' and press tab get
../folderC/
type in 'ls ../folder' and press tab get
folderA/ folderB/ folderC/
but 'ls ../folderB' get
ls: cannot access ../folderB: No such file or directory
the most strange point is, type in 'ls ../folder*' and press tab get
ls ../folderC/

How to understand this?

Comment 18 Roman Rakus 2010-11-10 14:05:27 UTC
`ls' uses physical path.
`bash' uses logical path.
And here bash completition gives you paths from logical path, but `ls' wants physical path.
But, what is strange, bash's globbing seems to use physical path. It means, completing `../folder' is not same as `../folder*'. I will investigate it.
Nevertheless, if you want consistent behaviour of bash and coreutils, use `set -P'.

Comment 19 Roman Rakus 2010-11-10 16:04:35 UTC
It seems that bash works a bit inconsistently. Bash has several types of completion. Command completion, file completion, glob completion and so on. And it looks like command completion and glob completion uses physical paths and file completion uses logical paths (by default). It means:
`../' and invoking completion will call command completion (physical)
`ls ../' and invoking completion will call file completion (logical)
`ls ../*' and invoking completion will call glob completion (physical)

I'm not sure if this is bug or expected behaviour. Use `set -P' and you will always use physical directory structure.

Comment 20 Roman Rakus 2010-11-10 16:41:34 UTC
I've asked upstream about that behaviour. I don't see it any archive yet.

Comment 21 martin 2012-04-13 16:32:31 UTC
Any news on this issue ? I just ran into a similar one.
If you go into the folderC symlink and type
 ls ../folderB[TAB]
it will complete to
 ls ../folderB[space]
while I would more expect
 ls ../folderB/

Digging inside readline, it looks like it comes from http://git.savannah.gnu.org/cgit/readline.git/tree/complete.c#n1694 where stat() fails.

While I understand the coreutils (ls/cp/mv) use physical paths, I would at least expect bash to be consistent in the way it uses its logical paths.

Comment 22 Fedora End Of Life 2012-08-16 22:16:08 UTC
This message is a notice that Fedora 14 is now at end of life. Fedora 
has stopped maintaining and issuing updates for Fedora 14. It is 
Fedora's policy to close all bug reports from releases that are no 
longer maintained.  At this time, all open bugs with a Fedora 'version'
of '14' have been closed as WONTFIX.

(Please note: Our normal process is to give advanced warning of this 
occurring, but we forgot to do that. A thousand apologies.)

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, feel free to reopen 
this bug and simply change the 'version' to a later Fedora version.

Bug Reporter: Thank you for reporting this issue and we are sorry that 
we were unable to fix it before Fedora 14 reached end of life. If you 
would still like to see this bug fixed and are able to reproduce it 
against a later version of Fedora, you are encouraged to click on 
"Clone This Bug" (top right of this page) and open it against that 
version of Fedora.

Although we aim to fix as many bugs as possible during every release's 
lifetime, sometimes those efforts are overtaken by events.  Often a 
more recent Fedora release includes newer upstream software that fixes 
bugs or makes them obsolete.

The process we are following is described here: 
http://fedoraproject.org/wiki/BugZappers/HouseKeeping


Note You need to log in before you can comment on or make changes to this bug.