0

I'm trying to make a link using:

ln -s /Backup files/ /link 1

Instead of making the link, I'm get the following output:

ln: target '/link' is not a directory

What am I doing wrong?

αғsнιη
  • 41,407
  • 1
    You need to quote spaces (or possibly avoid them altogether): `ln -s '/Backup files/' '/link 1'. Spaces in pathnames cause pain when used on the command line. – NickD Aug 17 '17 at 11:42
  • I'm not sure it's a duplicate of the other questions. But to tell you what you are doing wrong, we need to understand what you want to do and it's not clear. What is /Backup files/? One file? Several files? What is /link 1? – xhienne Aug 17 '17 at 12:43

2 Answers2

7

A shell will typically break a

ln -s /Backup files/ /link 1

command line into these words:

  • ln
  • -s
  • /Backup
  • files/
  • /link
  • 1

From the first word, it will derive the command to execute (something like /bin/ln found by searching all the directories listed in the $PATH variable for a file called ln) and will pass all those words as separate arguments to that /bin/ln executable.

ln will understand the second argument (-s) as an option that means create symbolic links instead of hard links, and then the rest as a number of non-option arguments. When ln receives more than two non-option arguments, it understands the last one as being a directory where to create symlinks to the other arguments.

So, that's asking ln to create 3 symlinks:

  • 1/Backup -> /Backup
  • 1/files -> files/
  • 1/link -> /link

If the 1 directory doesn't exist or if it's a file that is not of type directory, it will complain.

If you wanted ln to create a symlink called /link 1 that points to /Backup files/¹, you'd need to pass those arguments to ln:

  • ln
  • -s
  • /Backup files/
  • /link 1

In most shells, that can be done with:

ln -s '/Backup files/' '/link 1'

The ' characters, like the space characters, are part of the shell syntax. Here, they're used to tell that whatever is inside the '...' is to be treated literally. Specifically, the space character loses its signification as an argument delimiter and is instead included literally in the argument passed to ln. Some shell implementations support more quoting operators like "...", $'...', $"..." or backslash. In Korn-like shells like bash, all these are equivalent:

ln -s "/Backup files/" "/link 1"
ln -s $'Backup files/' $'/link 1'
ln -s Backup\ files/ /link\ 1

And you can of course combine them like:

'ln' "-"'s' "Back"up\ files/ ''""/link' '$'1'

¹ Note though that if link 1 existed and was of type directory (or symlink eventually resolving to a directory), ln -s 'Backup files/' '/link 1' would actually create a Backup files symlink in that directory instead (a /link 1/Backup files -> /Backup files/ symlink). With GNU ln, you can avoid that by using the -T option.

1

You are missing double quotes on your filenames. Since they contain spaces, they need to be quoted:

$ ln -s "/Backup files" "/link 1"
Kusalananda
  • 333,661
  • Not all shells support double-quotes as quoting operators. rc, es or akanga don't for instance (where " is not a special character). Single quotes would be more portable here (and also quote more characters). – Stéphane Chazelas Aug 17 '17 at 12:02