2

I'd like to use cp -b to copy a file to a destination, possibly creating a backup file of the destination path if it already exists. But, if the backup file already exists, I'd like to have cp fail with an error.

I know I can use -n to avoid clobbering the target file, but I want to instead refuse to clobber the backup file.

Is there a way to do that? I happen to be using GNU cp on Linux, and I'm willing to accept an answer that is specific to Linux if no POSIX option is available.

  • 3
    cp doesn't have to clobber backups. Use ` cp --backup=t` and it will create numbered backups with no clobbering. – John1024 Jul 15 '16 at 17:28
  • what is the difference between “avoid clobbering” and “refuse to clobber”? – ctrl-alt-delor Jul 15 '16 at 18:08
  • @richard It's not a semantic difference between "avoid clobbering" and "refuse to clobber"... it's a difference of which file I'm trying not to clobber. In my case, it's the backup file, not the target file. The target file already has an option not-to-clobber. The backup file does not appear to have such an option. – Christopher Schultz Jul 15 '16 at 19:12
  • 1
    @richard John posted the exact answer I was looking for, as a comment. If he posts it as an answer, I'll upvote + accept it. – Christopher Schultz Jul 15 '16 at 20:02
  • 1
    Note that no POSIX solution can be available, since there is no -b option. This is specific to GNU coreutils. – Fox Jul 15 '16 at 21:38
3

If you want to avoid clobbering any backup files with GNU cp, you can use numbered backups:

cp --backup=t  source destination

Rather than overwrite a backup, this creates additional backups.

Example

As an example, let's consider a directory with two files:

$ ls
file1  file2

Now, let's copy file1 over file2:

$ cp --backup=t file1 file2
$ ls
file1  file2  file2.~1~

As we can see, a backup was made.

Let's copy it again:

$ cp --backup=t file1 file2
$ ls
file1  file2  file2.~1~  file2.~2~

Another backup was made.

Documentation

From man cp, just before the end of the "description" section, the various possible options for --backup are itemized:

The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX. The version control method may be selected via the --backup option or through the VERSION_CONTROL environment variable. Here are the values:

none, off
     never make backups (even if --backup is given)

numbered, t
     make numbered backups

existing, nil
     numbered if numbered backups exist, simple otherwise

simple, never
     always make simple backups

As a special case, cp makes a backup of SOURCE when the force and backup options are given and SOURCE and DEST are the same name for an existing, regular file.

0

If you always use this to copy only one file, you can create a shell function, possibly in your ~/.bashrc like

cpb () 
{ 
    if [ -r "${2}/${1}~" ] ; then 
        echo "backup of '$1' exists in '$2'"
    else 
        cp -b "$1" "$2"
    fi
}

and use it like this:

$ mkdir dir
$ cpb x dir
$ cpb x dir
$ cpb x dir
backup of 'x' exists in 'dir'
$ ls -l dir
insgesamt 0
-rw-r--r-- 1 ott ott 0 Jul 16 01:09 x
-rw-r--r-- 1 ott ott 0 Jul 16 01:08 x~

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.