skip to Main Content

I want to serve some static files under the directory /var/www I would like to swap in a new set of files (which exist as, for example, /var/data/example) every few days or so. The server does not follow symlinks (the host is Linux).

So the curious thing is that when I try a hardlink I get an EPERM:

fs.link('/var/data/example', '/var/www');

This is a bit surprising, since I can create /var/www. What’s more if I do this:

fs.rename(`/var/data/example', '/var/www')

it works! I am mystified by this. I would rather use links, as it allows me to preserve what used to be there, rather than clobbering it.

Does anyone know why this might be happening?

2

Answers


  1. From your example (you didn’t explicitely say, but /var/www is usually a directory, so I take /var/data/example is too), it seems that your are trying to hard link a directory.

    That can’t be done on most filesystem (and in particular, can’t be done with ext4, which is the most likely — tho I only guess from heuristic reasonning. /var/www means unix. Probably linux. So probably ext4).

    Login or Signup to reply.
  2. As noted in another answer, hard links don’t generally work on directories. Any tools that allow this on arbitrary FS actually traverse a directory and link each file.

    If this is the intention here then this needs to be done by traversing a directory recursively:

    async function linkDir(sourceDir, targetDir) {
      await fsPromises.mkdir(targetDir, { recursive: true });
      const files = await fsPromises.readdir(sourceDir, { withFileTypes: true });
    
      for (const file of files) {
        const sourcePath = path.join(sourceDir, file.name);
        const targetPath = path.join(targetDir, file.name);
    
        if (file.isDirectory()) {
          await linkDir(sourcePath, targetPath);
        } else if (file.isFile()) {
          await fsPromises.link(sourcePath, targetPath);
        }
      }
    }
    

    It’s unknown why link was preferred, but this approach is susceptible to any pitfalls that are inherent to it, e.g. the contents of a hard link can be accidentally modified and changed in other places, and a hard link needs to be unlinked first before it could be overwritten. In case this is undesirable, cp is a reasonable alternative.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search