1

When running cp command to copy files, I would like to be prompted for overwrite confirmation, and, if possible, view the file diff confirming.

Is this possible? And if yes, how?

Ideal example:

$ cp file1.txt file2.txt
0a1,2
> 1.
> 
2a5,6
> 2.
> 
4a9,10
> 3.
> 
Overwrite file2.txt? [Yes/No/Keep both] (default Y): 
  • This can be easily done with a script. Before providing an answer: what do you want done in case the files are binary? – nohillside Jun 17 at 8:41
  • 1
    I do not plan to use on binary files, but I guess a simple "binaries differ" info would be enough. Script.. I hoped there was some way to do it with cp parameters or another built-in command. – scrrr Jun 17 at 9:20
  • 1
    Have you looked at the manual for cp? – fd0 Jun 17 at 11:24
  • 1
    Shell scripts basically combine built-in commands, so to speak :-) – nohillside Jun 17 at 13:06
  • I'd recommend using a different command name (not cp) -- this is a significantly different function, and using the same name is likely to cause mistakes. – Gordon Davisson Jun 18 at 4:41
2

Placing alias commands in your bash profile will gain you partial overwrite protection. As others mentioned in your comments, you will need to write a script add the diff function.

I placed the commands below in my ~/.bash_profile.

Bash on macOS determines what file is your bash profile in this order:

  1. ~/.bash_profile

  2. ~/.bash_login

  3. ~/.profile

These commands tell cp, mv and rm to give you a warning when a file is to be overwritten or deleted:

alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -i'
# Placing a blank after sudo causes alias substitution 
# for sudo's inner commands . See Gordon Davisson's comments below for 
# details. 
alias sudo='sudo '

This example, assumes you have placed the above commands in your bash profile.

mac $ touch a
mac $ touch aa
mac $ cp aa a
overwrite a? (y/n [n]) n
not overwritten
mac RC=1 😱  $ rm a
remove a? 
mac $ mv aa a
overwrite a? (y/n [n]) n
not overwritten
# demonstrate sudo protection
mac $ touch inin
mac $ sudo cp inin hihi
overwrite hihi? (y/n [n]) n
not overwritten
mac RC=1 😱  $ sudo mv  inin hihi
overwrite hihi? (y/n [n]) n
not overwritten
mac $ sudo rm inin hihi
remove inin? y
remove hihi? y
mac $ 

These alias command do not protect you in all circumstances like when you invoke a new shell or run cp, mv or rm from within other commands like find.


P.S.: The aliases mentioned above use the same name as the original command, thereby shadowing it. To access the original un-aliased command, prepend it with a \ character (E.g., \cp, \mv, \rm etc.).

  • 1
    If you alias sudo to itself with a space at the end (i.e. alias sudo='sudo '), the shell will expand aliases after it and these protections will be applied after sudo (i.e. sudo mv ... would expand to sudo mv -i ...). But this won't apply them in other contexts, such as find ... -exec mv ..., or when you open a root shell with sudo -i or sudo su. – Gordon Davisson Jun 18 at 20:48
  • I didn't know about the \ prefix! Great – scrrr Jun 19 at 7:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .