Changing directory with cd to a symlinked folder can have unexpected consequence on how certain commands in bash behave.
For instance, assume that we have the following file structure where active_project is a symlink to a folder nested in an adjacent file tree:
.
├── data
│ ├── project1
│ │ ├── 01-01.csv
│ │ ├── 01-02.csv
│ │ └── 01-03.csv
│ └── project2
│ ├── 02-aa.csv
│ └── 02-ab.csv
└── active_project -> data/project2Commands ls and cd
Once we change directory into active_project (symlink), the commands ls and cd will interpret .. (the parent folder) differently and show different contents in the parent of active_project:
$ cd active_project/
$ ls ..
project1 project2
$ (cd .. && ls)
data active_projectThe command ls shows the contents of the parent folder of the real working directory data/project2. Conversely, cd shows the contents of the parent of the symlink itself active_project. This different outcome is due the different type of program behind these two commands.
- The command
cdis a built-in command in bash and as such, it works with the path reported bypwd, which is aware of the actual file path followed by the user in this shell environment in the past. Hence,cdwill follow the symlink backwards. - The command
lsis a standalone application and it works with the real path or physical path of the current folder. It does not have any knowledge of what happened in this shell environment in the past.
Completion of commands
TAB completion can also behave differently depending on the default settings of bash in your Linux distribution or if extra bash completions are included. The built-in completion for cd in bash should follow the symlink on .. backwards, as cd does on execution. If that’s not the case, an external bash completion might be interfering. You can switch back to the built-in completion for cd with the following command in your .bashrc:
complete -r cd