I have a /usr/tomcat6/logs
directory linked to /var/log/tomcat6
.
When I changed directory to /usr/tomcat6/logs
and try to ls
files using a relative pathname ../conf/Catalina/localhost
, a No such file or directory error occurs. However, cd ../conf/Catalina/localhost
works.
See the following:
[root@fedora ~]# ll /usr/tomcat*
lrwxrwxrwx. 1 root root 21 Jun 17 15:00 /usr/tomcat6 -> apache-tomcat-6.0.32/
lrwxrwxrwx. 1 root root 21 Jun 17 13:03 /usr/tomcat7 -> apache-tomcat-7.0.16/
[root@fedora ~]# cd /usr/tomcat6
[root@fedora tomcat6]# ll logs
lrwxrwxrwx. 1 root root 16 Jun 17 14:51 logs -> /var/log/tomcat6
[root@fedora tomcat6]# cd logs
[root@fedora logs]# cd ../conf/Catalina/localhost
[root@fedora localhost]# pwd
/usr/tomcat6/conf/Catalina/localhost
[root@fedora localhost]# cd /usr/tomcat6/logs
[root@fedora logs]# ll ../conf/Catalina/localhost
ls: cannot access ../conf/Catalina/localhost: No such file or directory
How could this happened? Is it a bug or special behaviour of symbolic link?
Best Answer
It is special behavior of
bash
'scd
builtin; the relative file behavior is the natural one. Once you follow a symbolic link, you are in the actual path of the target and the original path information is lost; but if you usebash
orzsh
tocd
there then the shell remembers the original path and uses it in future relativecd
commands. But not in relative filename references, becausebash
doesn't actually know if you intended a filename or something else.If you look at the
cd
documentation inbash
, you'll see there are-L
and-P
options which tell it whether to use "logical" (remembering the original path) or "physical" (using the filesystem's idea) paths.If you need to have the "logical" behavior at all times, you need to use a
--bind
mount (on Linux; Solaris and other OSes call it "loopback" or other things) instead of a symlink.