MacOS: How to "cd" into a symlink?

I have a folder "abc". I create a symlink: ln -s abc abclink. but then, whan I type, cd abclink it says "No such file or directory".

I can see the link, it has "lrwxr-xr-x" permissions, why doesn't it work? How to make it work?


Usually when you run into that, your target is invalid. i.e. abc doesn't exist. Yes, you can create symlinks to things that don't exist.


I had an extra confusing use case which is ultimately the same as the accepted answer—the destination directory didn't exist—but with an extra twist.

I was creating a symlink to a directory defined in an environment variable we'll call FOO:

$ FOO="~/project"
$ ln -s foo "$FOO"

This seemed to work fine:

$ ls -al
lrwxr-xr-x   1 jondoe  jondoe    10 Feb 20 02:25 foo -> ~/project

However, when I'd try to go into the foo folder, I'd get an error:

$ cd foo
-bash: cd: foo: No such file or directory

This was weird, because we just saw that foo definitely exists. Moreover, so does ~/project:

$ cd ~/project
$ ls -al
drwxr-xr-x  3 jondoe  jondoe  102 Feb 20 02:26 .
drwxr-xr-x  4 jondoe  jondoe  136 Feb 20 02:25 ..
-rw-r--r--  1 jondoe  jondoe    0 Feb 20 02:26 README.md

How could the symlink and the folder it's pointing to both exist, but I can't actually use the symlink?

It turns out the cause is that the FOO environment variable had a tilde ~ in it. Since I wrapped this variable in quotes when creating the symlink, the tilde did not go through bash expansion, and so the resulting symlink pointing to the literal path ~/project rather a project folder in my home directory.


A possible source of this problem: if the target directory contains spaces, you don't need to put quotes around the value inserted by hitting the Tab key, because the Terminal escapes the spaces with backslashes for you.

For example, assuming there is a directory /tmp/Dir With Spaces/:

ln -s /tmp/Dir\ With\ Spaces link1      <-- This works
ln -s "/tmp/Dir With Spaces" link2      <-- As does this
ln -s "/tmp/Dir\ With\ Spaces" link3    <-- But this one doesn't

You can see why by looking at the output from ls -l:

lrwxr-xr-x    1 dave  staff          21 Jul 19 10:30 link1 -> /tmp/Dir With Spaces/
lrwxr-xr-x    1 dave  staff          21 Jul 19 10:31 link2 -> /tmp/Dir With Spaces/
lrwxr-xr-x    1 dave  staff          23 Jul 19 10:31 link3 -> /tmp/Dir\ With\ Spaces/

Either escape the spaces in the path with backslashes, or enclose the unescaped path in quotes, not both.