Trailing slash in BSD and GNU cp and find commands

What might be a reason that BSD cp and find don't "like" a trailing slash for directory names?

Code:
|     |            cp            |            mv            |
|-----|--------------------------|--------------------------|
|     | # to copy dir1/ contents |                          |
|     | cp -a dir1/* dir2/       | # to move dir1/ contents |
| GNU |                          | mv dir1/* dir2/          |
|     | # to copy dir1/ itself   |                          |
|     | cp -a dir1/ dir2/        | # to move dir1/ itself   |
|-----|--------------------------| mv dir1/ dir2/           |
|     | # to copy dir1/ contents | # mv dir1 dir2/ works    |
|     | cp -a dir1/ dir2/        | # same, but I don't      |
| BSD |                          | # consider this syntax   |
|     | # to copy dir1/ itself   | # really correct[^1]     |
|     | cp -a dir dir2/          |                          |

A similar issue with BSD find. It adds a trailing slash after the source path automatically, and so, if, for the sake of consistency[^1], you already added it manually, as in find ./ -type f, the first / will be replaced with // instead. Though it doesn't break anything (at least, until you need to parse it), it looks ugly:

Code:
.//file1
.//file2
.//dir1/file3
.//dir2/file4

[^1]: Because the root directory in Unix and Unix-like operating systems is /, I consider a trailing / to be not an excessive or optional but instead a mandatory (though its omission is often forgiven by the tools we use) part of directory names, and so I always refer to them like /usr/bin/ and not /usr/bin (and to refer to their contents, /usr/bin/*).

According to this: https://stackoverflow.com/a/24925767 answer on Stack Overflow, usually we should not put a trailing slash after the source directory when using the cp command. And on the first glance (and given that I'm not a really command-line skillful guy), it may look as the reason why BSD cp has its behavior. But then why BSD mv doesn't follow the same behavior pattern? And therefore it doesn't really seem that the answer on Stack Overflow explains why BSD cp behaves so.
 
I always put a final slash to make sure it's a directory and not another file. But then, writing portable shell scripts is an exercise in futility.
 
What might be a reason that BSD cp and find don't "like" a trailing slash for directory names?
Don't know, for copying whole directories or trees, I always use rsync instead of cp -a.
Cracauer's question about POSIX is very good.

A similar issue with BSD find. It adds a trailing slash after the source path automatically, ...
It does not:
Code:
mkdir test
cd test
touch foo
mkdir bar
touch bar/blatz
find foo bar
find .
The first command will output foo, bar, and bar/blatz, without any extra slashes. The second command will output ./foo, ./bar and ./bar/blatz. It makes perfect sense: find adds a slash after any argument that is a directory if something is concatenated to the argument, to make sure the result is a syntactically valid path.

and so, if, for the sake of consistency[^1], ...

[^1]: Because the root directory in Unix and Unix-like operating systems is /, I consider a trailing / to be not an excessive or optional but instead a mandatory (though its omission is often forgiven by the tools we use) part of directory names, and so I always refer to them like /usr/bin/ and not /usr/bin (and to refer to their contents, /usr/bin/*).

It is your prerogative to add slashes according to your taste. You can also use double slashes if you like instead of single slashes. But please be aware that your particular convention is not shared widely, neither by other people nor by tools. As such, tools may normalize paths (remove double slashes, trailing slashes, and simplify constructs such as ..././... and .../a/../b/...) that don't change semantics.

A particularly insidious example of meaning being attached to slashes that are semantically not needed is rsync: If you add a trailing slash to a directory name, rsync interprets the name as being "all the content of the directory", if not as "the directory itself". I've always considered this to be a terrible misfeature and nasty hack. And I've had Tridge explain to me (over beer or iced tea) that it is a great user interface and wonderful simplification. Which proves that different people can come to different conclusions, based on different tastes.
 
[^1]: Because the root directory in Unix and Unix-like operating systems is /, I consider a trailing / to be not an excessive or optional but instead a mandatory (though its omission is often forgiven by the tools we use) part of directory names).
If you'd have a look what actually ends up on the disk, I'm sure you'd discover that not to be the case.
 
Back
Top