This depends on what Unix you are using.
On some BSD systems (OpenBSD, FreeBSD), you will find that cp -f
will unlink (remove) the symbolic link and replace it with the source.
Using GNU cp
, this would not have the same effect, and you would need to use the long option --remove-destination
instead.
On macOS, use cp -c
to, as the manual says, "copy files using clonefile(2)
".
On NetBSD, use cp -a
("archive mode", the same as cp -RpP
on that system). This doesn't work on GNU, macOS, OpenBSD, or FreeBSD, even though all of these systems have the same or similar -a
option for cp
(on GNU systems, it's the same as -dR --preserve
).
You already mention this yourself: Removing the link before copying the file will solve the issue. The rm
utility removes the link rather than the file referenced by the link. This is also the most portable way to replace a symbolic link with a regular file.
If you are writing a script, then I suggest that you use rm
followed by cp
.
If you are working interactively and keep forgetting to do this, then it's also likely that you forget to use a specific option with cp
for these situations.