Is it "do one thing at one time"?
This comment sounds like a question about a general design principle. Often, questions about these are very subjective, and we are not able to write a proper answer. Be warned that we may close questions in this case.
Sometimes we have an explanation for the original design choice, because the developer(s) have written about them. But I don't have such a nice answer for this question.
Why cp
is designed this way?
The problem is Unix is over 40 years old.
If you were creating a new system now, you might make different design choices. But changing Unix would break existing scripts, as mentioned in other answers.
Why was cp
designed to silently overwrite existing files?
The short answer is "I don't know" :-).
Understand that cp
is only one problem. I think none of the original command programs protected against overwriting or deleting files. The shell has a similar problem when redirecting output:
$ cat first.html > second.html
This command also silently overwrites second.html
.
I am interested to think how all these programs could be redesigned. It might require some extra complexity.
I think this is part of the explanation: early Unix emphasized simple implementations. For a more detailed explanation of this, see "worse is better", linked at the end of this answer.
You could change > second.html
so it stops with an error, if second.html
already exists. However as we mentioned, sometimes the user does want to replace an existing file. For example, she may be building up a complex command, trying several times until it does what she wants.
The user could run rm second.html
first if she needs to. This might be a good compromise! It has some possible disadvantages of its own.
- The user must type the filename twice.
- People also get in to a lot of trouble using
rm
. So I would like to make rm
safer as well. But how? If we make rm
show each filename and ask the user to confirm, she now has to write three lines of commands instead of one. Also, if she has to do this too often, she will get into a habit and type "y" to confirm without thinking. So it could be very annoying, and it could still be dangerous.
On a modern system, I recommend installing the trash
command, and using it instead of rm
where possible. The introduction of Trash storage was a great idea e.g. for a single-user graphical PC.
I think it is also important to understand the limitations of the original Unix hardware - limited RAM and disk space, output displayed on slow printers as well as the system and development software.
Notice that original Unix did not have tab completion, to quickly fill in a filename for an rm
command. (Also, the original Bourne shell does not have command history, e.g. like when you use the Up arrow key in bash
).
With printer output, you would use line-based editor, ed
. This is harder to learn than a visual text editor. You have to print some current lines, decide how you want to change them, and type an edit command.
Using > second.html
is a bit like using a command in a line-editor. The effect it has depends on the current state. (If second.html
already exists, its content will be discarded). If the user is not sure about the current state, she is expected to run ls
or ls second.html
first.
"Simple implementation" as a design principle
There is a popular interpretation of Unix design, which begins:
The design must be simple, both in implementation and interface. It is more important for the implementation to be simple than the interface. Simplicity is the most important consideration in a design.
...
Gabriel argued that "Worse is better" produced more successful software than the MIT approach: As long as the initial program is basically good, it will take much less time and effort to implement initially and it will be easier to adapt to new situations. Porting software to new machines, for example, becomes far easier this way. Thus its use will spread rapidly, long before a [better] program has a chance to be developed and deployed (first-mover advantage).
https://en.wikipedia.org/wiki/Worse_is_better
If you want to change the behavior, alias 'cp' to 'cp -i' or 'cp -n'.
– kevlinux Oct 24 '18 at 04:11cp foo bar && some-command --input-file bar
. This would be using an olderbar
if thecp
created instead abar (copy)
file. Of course I could addrm foo
at the beginning, but that shouldn't be necessary, and by havingcp
overwrite the destination file it isn't. – Carlos Campderrós Oct 24 '18 at 15:32cp
tocp -i
or similar because you'll get used to having a safety net, making systems where it's not available (most of them) that much more risky. Better to teach yourself to routinelycp -i
etc. if that's what you prefer. – Reid Oct 24 '18 at 19:55cp
is not an "app", whatever those things are. It's a Unix tool: Unix never says PLEASE; it also never says SORRY. It does what you tell it to do. If you tell it to do dumb things, then the fault my dear Horatio lies not with your Unix*
s but with your own faulty orders. :) We don't need Clippy to popup a window saying "Are you really, really sure?" every time we want to increment a machine register. – tchrist Oct 24 '18 at 21:44git checkout -p
commands. About a minute per year. If I had to confirm every file I wanted to be overwritten bycp
, it would take me about five minutes every week. (Not for the confirmation itself, but for figuring out why it happens and how I should pre-remove those files in the future.) – leftaroundabout Oct 24 '18 at 21:48cp
is to overwrite its target (if it's a file), what is your issue with this? Given that your GUI thingy works differently, why is your issue not with that tool instead? If this question, instead of asking "why?", asked "how?" (i.e. "how may I makecp
do what my GUI tool does?"), it would be easier to answer in an opinion-neutral way. – Kusalananda Oct 25 '18 at 05:35cp -al
is not designed to silently overwrite, though. – Martin Braun Jun 20 '23 at 03:02