3
ls ..

means ‘list upper directorie’s files and directories.’

When I changed directory following a symbolic link, ls .. does not follow the symblic link. It just shows the real upper directory.

For example, when the directory structure is as follows,

r ┬ a - b - sub@
  └ sub

(sub@ is a symbolic link to sub directory)

ls ..command after cd a/b/sub gives files at r directory as I’m in r/sub. not b directory’s. But cd .. command takes me to b directory.

How can I use ls command to show files in directory b?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
plhn
  • 5,017
  • 4
  • 47
  • 47
  • Why are you upvoting a clearly off-topic question? – m0skit0 Sep 02 '15 at 13:44
  • 1
    @m0skit0 Shell scripting is programming. This question is overlapping betwen Super User, Unix, and Stack Overflow. – fuz Sep 02 '15 at 13:45
  • 4
    @FUZxxl, shell scripting *is* programming, which I firmly believe (as someone with a gold badge in both "bash" and "shell" here), but I'm still not convinced that this is a good fit here. This reads more as "how do basic UNIX tools behave?", as opposed to anything particularly relevant for scripted use. – Charles Duffy Sep 02 '15 at 13:46
  • 3
    possible duplicate of [Behavior of cd/bash on symbolic links](http://stackoverflow.com/questions/10456784/behavior-of-cd-bash-on-symbolic-links) – Joe Sep 02 '15 at 13:55
  • @FUZxxl Nowhere in the question it is stated this is a script. And definitely the question is not about scripting but about the tools themselves. – m0skit0 Sep 02 '15 at 13:59

1 Answers1

4

A directory doesn't know what symbolic link you used to get to it; .. is an actual directory entry that points to the real parent directory. But when you use the shell command cd .., bash cheats. It knows what path you used to get there (it's in $PWD), so it just removes the last component of that and changes to the resulting directory.

You can use the same trick yourself for the benefit of other commands by using "${PWD%/*}" instead of ..:

ls "${PWD%/*}"
Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • Please don't use `${PWD%/*}`; this has several issues. Use `$(dirname $PWD)` instead. – fuz Sep 02 '15 at 13:43
  • 1
    @FUZxxl What issues? The only one I know of is the corner case where `dirname` returns `.` and the substitution will not which doesn't apply here. – Etan Reisner Sep 02 '15 at 13:45
  • 2
    @FUZxxl, if you're going to try to promote best practices, at least make it `dirname "$PWD"`. Otherwise, you're creating more bugs than you fix. – Charles Duffy Sep 02 '15 at 13:45
  • 4
    @EtanReisner Right, `$(dirname "$PWD")` is even better. The substitution does not work correctly on a path like `foo//bar` or on the root directory. It can also fail on relative paths. It also fails on `foo/bar/`. `dirname` uses a [fairly complex algorithm](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/dirname.html) to deal with all possible situations. – fuz Sep 02 '15 at 13:49
  • 2
    Then again, if you're going to use a subshell anyway, you could just `(cd .. && ls)`. How about a function? `symls() ( cd "$@" && ls )`? You can use it like `symls ..`, or go crazy and do `symls -P ..` to completely dereference the path. – kojiro Sep 02 '15 at 13:59
  • @plhn, inside `( )`, the `cd -` is completely unnecessary; the effect of the `cd ..` goes away when the subshell it's confined to exits. – Charles Duffy Sep 02 '15 at 14:06
  • @CharlesDuffy you’re right. – plhn Sep 02 '15 at 14:07
  • It would need to be `"$(dirname "$PWD")"` with double quotes around both the inner parameter expansion and the outer command substitution. It is more general, but since `PWD` is always an absolute pathname, I'm not sure how necessary it is in this case. – Mark Reed Sep 02 '15 at 14:35
  • @FUZxxl I was inspired to try writing a shell built-in `dirname` and put it [on codereview.stackexchange](http://codereview.stackexchange.com/q/102622/28012). I looked but couldn't find any good test data (other than in the spec link to test it with). – Etan Reisner Sep 03 '15 at 14:31