24

Is there a proper way to link /home/user/app/public to /home/user/public_html, considering the fact that the target already exists?

If I do ln -s /home/user/app/public /home/user/public_html, I end up having /home/user/public_html/public.

I guess it would be possible also to inverse the action such as ln -s /home/user/public_html /home/user/app/public, however I'm not sure how to avoid /home/user/app/public/public_html as the end result.

user2094178
  • 343
  • 1
  • 2
  • 5

4 Answers4

20

Lemme understand your issue in the right way

Your source is /home/user/public_html and I assume it has files in there. And you want to make a link to this directory right in /home/user/app/public. In this way then, you could do something like ls /home/user/app/public and see the files on that exist on /home/user/public_html.

If this is correct, then your source is /home/user/public_html and the target is /home/user/app/public. The proper command is this one:

ln -s /home/user/public_html /home/user/app/public

Just make sure that /home/user/app/public isn't a valid directory or file previous enter the command.

Lucio
  • 18,843
  • 10
    This is an old one, but I think the user asked exactly how to do what you describe, but, in the case that /home/user/app/public may already exist (which is exactly the caveat you mention at the end of your answer). So IMHO this doesn't answer the original question as the user wanted to know precisely how to deal with an already existing target (ie. how to override it with the symlink, without having to delete it prior to creating the symlink). – jotadepicas May 31 '18 at 18:55
  • Try it -T option :) – Milkmannetje Nov 21 '18 at 16:51
3

If I understand your question correctly, you wanted to know how to deal with already existing targets. If that's the case, there are two possible scenarios.

1) the existing target is a file. If this is the case, you can force the creation of the symlink with "-f"

2) the existing target is a directory. If this is the case, then it depends on your current implementation of the ln command. It could have the "-n" argument available, which causes symlink to directories be handled properly, instead of duplicating them as you say.

Reference: https://unix.stackexchange.com/questions/207294/create-symlink-overwrite-if-one-exists

2

I'm not going to get into an elaborate discussion of this as the correct answer has already been selected, but ln simply doesn't work in that way.

An alternative solution would be to use mount instead of ln. I believe the correct command in this case would be:

sudo mount --bind ~/app/public ~/public_html

Notice the caveat to doing it this way, however: in my experience mount requires privilege so you're going to have to sudo it. For this reason you can't put it in .profile as that will lock up your session. You could put it in a script, or you could add it to /etc/fstab. I don't generally add bound mounts to fstab, but I believe the entry would be:

/home/user/app/public /home/user/public_html none defaults,bind 0 0

or something very similar. I'm also pretty certain that you can't use relative paths in fstab, so the paths must be absolute, as I've shown here.

Ian Moote
  • 121
0

As @jotadepicas and @Milkmannetje allude to in the comments, there are a couple ways to deal with this.

Assuming your source is $source and destination is $target.

  1. Remove the target manually first. This should work on Linux and Mac consistently.

    rm "$target"
    ln -s "$source" "$target"
    
  2. If you're on Linux you can use the -T option.

    ln -sT "$source" "$target"
    
  3. If you're on macOS you can use the -F option.

    ln -sF "$source" "$target"