Should I put trailing slash after source and destination when copy folders

user2507818 picture user2507818 · Aug 10, 2013 · Viewed 15.5k times · Source

I want to copy:

  • This folder: ajax (/home/thej/public_html/JC/ajax).
  • Into this folder: /home/thej/public_html/demo/conf/. The final result will be /home/thej/public_html/demo/conf/ajax.

I know the cp command should be something like:

cp -r /home/thej/public_html/JC/ajax /home/thej/public_html/demo/conf

My question is:

  1. should I put / after ajax, ajax/?

  2. should I put / after conf, conf/?

I googled online, some put '/', some not, so really confused with it.

Answer

Volker Siegel picture Volker Siegel · Jul 24, 2014

No trailing slash on source directory

You should not put a trailing slash on the source directory:

The point is relevant to cp - but also to mv, where it is much more important.

I'll cite the warning from the manual - note that it's not found in the man page, but in the info page info coreutils 'mv invocation':

Warning: Avoid specifying a source name with a trailing slash, when it might be a symlink to a directory. Otherwise, 'mv' may do something very surprising, since its behavior depends on the underlying rename system call. On a system with a modern Linux-based kernel, it fails with 'errno=ENOTDIR'. However, on other systems (at least FreeBSD 6.1 and Solaris 10) it silently renames not the symlink but rather the directory referenced by the symlink.

Use trailing slashes on destination directory

If you want to move files and directories into a directory, you should add a trailing slash to the destination directory.
It does not change anything as long as all goes well.
But it can save you from a common error that causes loosing or changing data:

If you move a file into a directory, there are two things that can go wrong:
You may have misspelled the last component of the destination directory name, like one wrong character. Two of the things that can happen are these two cases:

  • If the misspelled name does not exist:

    • the file will be renamed to the misspelled name

    • it gets moved into the parent directory of the intended destination

    • So it ends up neither were it was, not where you expect it to go.

  • If the misspelled name does exist, and is a file:

    • the file will overwrite the file with the misspelled name, in the parent directory of the destination.

    • Again, you will not find it were it was, or where it should be: it just vanished.

If you use a trailing slash on the destination directory, both cases are prevented:

It makes mv not use it as a file name when it normally would do. Instead, mv just gives an error:

mv: failed to access ‘foo/’: Not a directory

Automatically remove slashes

There is a special option for cp and mv to mitigate the risk by allways stripping the slash from src dirs:

Some GNU programs (at least `cp' and `mv') allow you to remove any
trailing slashes from each SOURCE argument before operating on it.  The
`--strip-trailing-slashes' option enables this behavior.

   This is useful when a SOURCE argument may have a trailing slash and
specify a symbolic link to a directory.  This scenario is in fact rather
common because some shells can automatically append a trailing slash
when performing file name completion on such symbolic links.  Without
this option, `mv', for example, (via the system's rename function) must
interpret a trailing slash as a request to dereference the symbolic link
and so must rename the indirectly referenced _directory_ and not the
symbolic link.  Although it may seem surprising that such behavior be
the default, it is required by POSIX and is consistent with other parts
of that standard.