I want to cp
a directory but I do not want to overwrite any existing files even it they are older than the copied files. And I want to do it completely noninteractive as this will be a part of a Crontab Bash script. Any ideas?
-
2https://unix.stackexchange.com/questions/67539/how-to-rsync-only-new-files – n611x007 Jun 26 '15 at 12:26
-
1[SuperUser - Copy files in linux but avoid the copy if files do exist in destination](https://superuser.com/questions/118781/copy-files-in-linux-avoid-the-copy-if-files-do-exist-in-destination) – cssyphus Aug 13 '22 at 19:23
-
**TL;DR:** For files, `cp -n copyFile pasteFile`, but for directories, `cp -r -n copyDir pasteDir` – Andrew Sep 25 '22 at 23:37
8 Answers
Taken from the man page:
-n, --no-clobber
do not overwrite an existing file (overrides a previous -i option)
Example:
cp -n myoldfile.txt mycopiedfile.txt

- 4,468
- 36
- 33

- 30,580
- 6
- 55
- 83
-
56Note, this will exit with an error if the file exists. To exit with success, try ```cp -n source.txt destination.txt || true``` – galenandrew Apr 01 '16 at 16:38
-
25@galenandrew `cp -n` does not exit with error if the file exists on Ubuntu 12.04. – amit kumar Aug 29 '16 at 09:47
-
@galenandrew Confirmed. Thank you. My project wasn't building in Xcode after adding a run script to my target. – Ruiz Apr 17 '17 at 20:30
-
-
3Even with Ubuntu 18.04, the behavior is the same, that when the file exists, the command exit without erro, that is, an no op! This is dangerous! – Yu Shen Jul 21 '20 at 18:44
-
`cp -n source.txt dest.txt || test -f dest.txt` won't ignore error if `source.txt` and `dest.txt` are missing – Jook Sep 24 '20 at 10:50
-
FWIW, I have noticed that a *needed* `-n` exits `1` on Arch, but exits `0` on Manjaro. So, the behavior seems to be connected to the stack, similarly to how `cp -i` is often a link for `cp` in `.bashrc` on desktop distros. I only found this because I didn't stop at testing on my desktop, but on the actual machine it would be used—always test on your identical setup, not merely a distro related to the stack. – Jesse Apr 04 '23 at 09:31
-
And, it would work for `cp -n myfolder/* newfolder/` with identical behavior, and will not break if encountering an existing file where the `-n` is needed. – Jesse Apr 04 '23 at 09:33
-
always read your man page - that's the main takeaway from this answer at least IMO – hovanessyan Apr 04 '23 at 15:07
Consider using rsync
.
rsync -a -v --ignore-existing src dst
As per comments rsync -a -v src dst
is not correct because it will update existing files.

- 4,691
- 2
- 30
- 33

- 8,192
- 3
- 24
- 22
-
10You want to add the `--ignore-existing` flag to prevent existing files from being overwritten. – Uyghur Lives Matter Aug 16 '14 at 18:22
-
8Complete command `rsync -a -v --ignore-existing
` is indeed the correct answer, instead of `cp -u`above. -
1If a previous copy was interrupted and only a truncated file copied, I'm sure cp -u won't re-copy it... but will rsync, with --ignore-existing? Probably not either... so that makes them perfectly equivalent, right? – dagelf Dec 16 '17 at 16:40
-
rsync keeps the file timestamp while cp uses the current time (in my experience) – Stefan Dec 27 '17 at 16:27
-
You can use `--preserve=timestamps` with `cp` to preserve the timestamps. – Wilson F Aug 10 '18 at 22:33
-
1
-
2absolutely. I don't want to install `rsync` into my docker container, just to do a copy! I can't imagine why we should use a cannon when a BB gun will suffice. – Auspex Jun 04 '19 at 13:01
cp -n
Is what you want. See the man page.

- 1,148
- 6
- 5
-
1The man page: `-n Do not overwrite an existing file. (The -n option overrides any previous -f or -i options.)` – rebane2001 Dec 16 '21 at 13:00
This will work on RedHat:
false | cp -i source destination 2>/dev/null
Updating and not overwriting is something different.

- 21,900
- 13
- 104
- 178
-
6
-
12
-
1Obviously, this command won't work if you'll try to copy more than ARG_MAX files. To work-around this case, check this [link](http://unix.stackexchange.com/a/110285). – mginius Oct 27 '15 at 15:55
-
12Also obviously, this command won't work if the earth crashes into the sun. – ceving Jan 27 '20 at 08:50
-
@ceving I think you'll find that `oh-my-zsh` has an alias for that use-case. – Michael Paulukonis Nov 06 '20 at 16:45
For people that find that don't have an 'n' option (like me on RedHat) you can use cp -u
to only write the file if the source is newer than the existing one (or there isn't an existing one).
[edit] As mentioned in the comments, this will overwrite older files, so isn't exactly what the OP wanted. Use ceving's answer for that.

- 16,518
- 7
- 45
- 61
-
14OP asked not to overwrite existing files **even if they are older than copied files**, so `-u` doesn't actually fit purpose. – Andrew Lott Feb 19 '14 at 10:39
-
5Goodness, you're absolutely right. I'm surprised it took so long for anyone to notice. – Grim... Feb 19 '14 at 15:20
-
It might not be what the OP asked for, but it's exactly what I needed for my Uberspace (Centos 7). Thanks! – Thomas Praxl Dec 11 '19 at 21:39
-
2
Alpine linux: Below answer is only for case of single file: in alpine cp -n
not working (and false | cp -i ...
too) so solution working in my case that I found is:
if [ ! -f env.js ]; then cp env.example.js env.js; fi
In above example if env.js
file not exists then we copy env.example.js
to env.js
.

- 85,173
- 29
- 368
- 345
Some version of cp do not have the --no-clobber option. In that case:
echo n | cp -vipr src/* dst

- 482
- 10
- 20
-
Super good suggestion. I lost a lot of time debugging scripts until I realised the --no-clobber option is not available everywhere. Thanks! – Raz Aug 25 '20 at 03:54
-
This works for me yes n | cp -i src dest

- 1
- 1
-
It is much more effective to use the '--no-clobber' instead of forcing interactive copy with negative input. – dash-o Aug 27 '20 at 05:25