0

I am in a directory which is a symlink

me@hostname:/home/me$ ls -al
the_link -> actual_a
actual_a
actual_b
actual_c
me@hostname:/home/me$ cd the_link
me@hostname:/home/me/the_link$

Now while I've had my shell open, some other process changed the symlink from the_link -> actual_a to the_link -> actual_b and possibly even did rm -rf actual_a. If I run a command in my shell it'll do weird things. Is there a way to tell cd to "re-cd" into the directory I'm in?

Obviously I can do

me@hostname:/home/me/the_link$ cd ..
me@hostname:/home/me$ cd the_link

but can I do it in one command?

4
  • What do you want to happen if actual_a was removed and then you try to cd to the directory you're in (actual_a) again? Succeed? Fail?
    – Sotto Voce
    Sep 30, 2022 at 2:03
  • @SottoVoce it should retry cding into the_link, not actual_a
    – user114651
    Sep 30, 2022 at 2:35
  • But if you had done a cd actual_a? Sep 30, 2022 at 8:58
  • Then I would've asked a different question.
    – user114651
    Sep 30, 2022 at 9:38

4 Answers 4

1
cd .

might work for you. If not, then there's of course

cd ../folder

which will go up one folder and into the named folder.

0
1

Some shells have a built-in version of pwd that keeps track of your current directory by following executions of cd. On the other hand, the /bin/pwd command determines your true position in the filesystem by traversing the filesystem from your current point to the root node, generating the directory path as it goes.

You can use this to get the directory path of your current location, and then you can force a change of directory to match that new reality

cd "$(/bin/pwd)"

Example

mkdir /tmp/x
cd /tmp/x


    # In another terminal
    mkdir /tmp/y
    mv /tmp/x /tmp/y/z


pwd                 # "/tmp/x"   - where the shell thinks you are
/bin/pwd            # "/tmp/y/z" - where you actually are

cd "$(/bin/pwd)"
pwd                 # "/tmp/y/z"

Obviously this cannot not work if some process has deleted the directory in which you reside, because there is no longer a path up through .. to the root.

3
  • POSIX pwd, builtin or not is required to print the contents of $PWD as long as it contains a path to the current working directory. You may have tested with GNU pwd which is only compliant in that regard when POSIXLY_CORRECT is in the environment. Sep 30, 2022 at 11:43
  • Your solution intends to do the equivalent of cd -P ., but it's rather the opposite of what the OP is asking AFAICT Sep 30, 2022 at 11:44
  • @StéphaneChazelas re pwd and $PWD - indeed, and for most people on a Linux-based system for most of the time, pwd doesn't always match the POSIX /bin/pwd. Re cd -P yes it does appear that I may have reinvented this. There are now some newer comments from the OP that offer some sort of attempt at a clarification, but at the time I wrote the answer it seemed like I was answering what was asked Sep 30, 2022 at 12:00
0

The approach I would take would be to cd to the full path to the symbolic link. That way, you'll always go to the real directory that the link points to.

Be sure to catch the error if the link points to a directory that doesn't exist. Something like:

base_path=/home/me
link_name=the_link
link_path="${base_path}/${link_name}"

cd ${link_path} || {
  echo "$0: Could not change directory to ${link_path}: Exiting"
  exit 2
}
0

Just do:

cd -- "$PWD"

(short for cd -L -- "$PWD").

$PWD in POSIX shells tracks the current working directory as updated by cd. It keeps the symlinks in there. So you'll end up in the new directory that the_link points to.

On the other hand:

cd -P .

Will stay in the current working directory but update $PWD so it contains a canonical absolute path, free of any symlink component. If the current directory has been removed though, that won't help and the behaviour will vary with the shell.

You must log in to answer this question.