168

I want to take down data in /path/to/data/folder/month/date/hour/minute/file and symlink it to /path/to/recent/file and do this automatically every time a file is created.

Assuming I will not know ahead of time if /path/to/recent/file exists, how can I go about creating it (if it doesn't exist) or replacing it (if it does exist)? I am sure I can just check if it exists and then do a delete, symlink, but I'm wondering if there is a simple command which will do what I want in one step.

1
  • If the destination exists, but is not a symlink, what do you want/expect to happen? Commented Jun 13, 2019 at 18:03

2 Answers 2

222

This is the purpose of ln's -f option: it removes existing destination files, if any, before creating the link.

ln -sf /path/to/data/folder/month/date/hour/minute/file /path/to/recent/file

will create the symlink /path/to/recent/file pointing to /path/to/data/folder/month/date/hour/minute/file, replacing any existing file or symlink to a file if necessary (and working fine if nothing exists there already).

If a directory, or symlink to a directory, already exists with the target name, the symlink will be created inside it (so you'd end up with /path/to/recent/file/file in the example above). The -n option, available in some versions of ln, will take care of symlinks to directories for you, replacing them as necessary:

ln -sfn /path/to/data/folder/month/date/hour/minute/file /path/to/recent/file

POSIX ln doesn’t specify -n so you can’t rely on it generally. Much of ln’s behaviour is implementation-defined so you really need to check the specifics of the system you’re using. If you’re using GNU ln, you can use the -t and -T options too, to make its behaviour fully predictable in the presence of directories (i.e. fail instead of creating the link inside the existing directory with the same name).

2
  • Thanks for the elaborate answer. When a symlink already exists and is overwritten - does it happen atomically? I.e. would there be a brief time window during which the symlink doesn't exist, and programs that try to access it during this time will fail?
    – obe
    Commented Nov 12, 2022 at 16:03
  • 1
    @obe that depends on the implementation. GNU ln replaces the file atomically: it creates the new symlink using a random name, then renames it to the desired name, overwriting the existing file instead of deleting it. Commented Nov 13, 2022 at 7:10
100

Please read the manual.

ln -sfn /new/target /path/to/symlink

$ man ln

-n, --no-dereference
treat LINK_NAME as a normal file if it is a symbolic link to a directory

15
  • 6
    Why is this the correct answer?
    – Mrchief
    Commented Jun 19, 2017 at 18:02
  • 15
    @Mrchief If /path/to/symlink is already a symlink to a directory, without the -n flag, you'll get the symlink created in /path/to/symlink/target instead of replacing /path/to/symlink
    – Flimm
    Commented Jun 22, 2017 at 10:42
  • 5
    Note that in macOS, this still doesn't work in some cases, for instances, when /path/to/symlink exists and is a directory, and but not a symlink. I think the only way to work around it is to run rm -rf first.
    – Flimm
    Commented Jun 22, 2017 at 10:47
  • 3
    This is the correct answer because it works for both files and directories.
    – tishma
    Commented Aug 27, 2022 at 17:44
  • 1
    I think you missed the point there, @JanusBahsJacquet. Yes, --force/-f does replace existing files or symlinks, but not entire directory trees, and nor should it. Try it for yourself: ln -snf path/to/any/target some-existing-dir. You'll find your symlink is created inside some-existing-dir rather than replacing it. If it deleted recursively, the simple, common error case of transposing target & destination arguments would regularly cause data loss.
    – Walf
    Commented Feb 1, 2023 at 0:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .