1. Introduction
The copy operation is a staple in any operating system (OS). Sometimes, we copy files to different directories as a safety measure for creating backups and organizing our data. Furthermore, copying important files also may also help preserve data integrity. In Linux, we can use the built-in cp command for copying files. The cp command comes with various options that we can utilize to further enhance its functionality.
In this tutorial, we’ll focus on two specific cp options: -f and –remove-destination.
First, we’ll discuss the cp command, to develop a basic understanding of the context. Next, we’ll talk about the -f and –remove-destination options, highlighting a subtle difference between them.
2. Understanding the cp Command
With cp, we can copy files or directories from one location to another:
$ cp file1.txt dir1
$ cp file1.txt file2.txt dir1
Here, we copy the file file1 to the directory dir1. After that, we copy the files file1.txt and file2.txt to dir1.
In this case, we’ve assumed that file1.txt, file2.txt, and dir1 are inside the current working directory. Otherwise, we need to provide their complete path.
Additionally, we can also use the cp command to copy the content of one file to another with a different filename:
$ cp file1.txt file2.txt
$ cp file1.txt dir1/file2.txt
Here, the cp command creates a new file named file2.txt and copies the content of file1.txt inside it. If file2.txt already exists, executing these commands replaces its content with that of file1.txt. Notably, although there is a switch to enable that behavior, by default, the cp command doesn’t prompt the user to confirm before overwriting files as it focuses on efficiency. So, we must be cautious while using the cp command to avoid unintentional overwrites.
However, there’s a small catch: we can only use cp to copy files if we’ve got the write permission for destination files. Otherwise, the cp command won’t be able to write any content:
$ cp file1.txt file2.txt
cp: cannot create regular file 'file2.txt': Permission denied
If we’re copying multiple files, the cp command only copies those files that have the write permission while discarding others.
In such a situation, we can interchangeably use the cp -f or cp –remove-destination commands.
3. Understanding the cp -f Command
The -f option forces cp to copy even if the destination files lack write permission. Otherwise, the -f option behaves like the regular cp command.
When we use the cp -f command, it first attempts to open the destination file. If the file doesn’t have the write permission, it replaces the existing file with a new file having the same name and copies the content inside it. As a result, this process also changes the metadata information of the destination file, such as permissions and timestamps. Naturally, we should still have permissions over the file such as ownership, so we can delete it.
Let’s suppose we’ve got file2.txt and file3.txt. First, we can verify their current status using the stat command:
$ stat file2.txt file3.txt
File: file2.txt
Inode: 1184574
Access: (0664/-rw-rw-r--)
Access: 2024-01-15 21:19:32.673142483 +0500
Modify: 2024-01-15 21:19:32.673142483 +0500
Change: 2024-01-15 21:19:32.673142483 +0500
Birth: 2024-01-15 21:19:32.669142365 +0500
File: file3.txt
Inode: 1184575
Access: (0444/-r--r--r--)
Access: 2024-01-15 21:19:32.673142483 +0500
Modify: 2024-01-15 21:19:32.673142483 +0500
Change: 2024-01-18 01:33:55.266597720 +0500
Birth: 2024-01-15 21:19:32.673142483 +0500
Next, we use the cp -f command to copy the content of file1.txt into both file2.txt and file3.txt:
$ cp -f file1.txt file2.txt
$ cp -f file1.txt file3.txt
Both commands execute successfully without any errors. Now, let’s take a look at the metadata information of both files again using the stat command:
$stat file2.txt file3.txt
File: file2.txt
Inode: 1184574
Access: (0664/-rw-rw-r--)
Access: 2024-01-15 21:19:32.673142483 +0500
Modify: 2024-01-18 01:39:15.559008841 +0500
Change: 2024-01-18 01:39:15.559008841 +0500
Birth: 2024-01-15 21:19:32.669142365 +0500
File: file3.txt
Inode: 1184564
Access: (0664/-rw-rw-r--)
Access: 2024-01-18 01:39:21.135205972 +0500
Modify: 2024-01-18 01:39:21.135205972 +0500
Change: 2024-01-18 01:39:21.135205972 +0500
Birth: 2024-01-18 01:39:21.135205972 +0500
Here we can see that the inode for file2.txt remains the same before and after the file copy operation. This shows that we had write permissions for file2.txt before the copy.
In contrast, file3.txt has a new inode after copying file1.txt into file3.txt which shows that a new file has been created. Moreover, all other metadata has also been updated for file3.txt.
4. Understanding the cp –remove-destination Command
The cp –remove-destination command removes destination files and creates new files with each execution irrespective of their write permission. This contrasts with the -f option, which only removes the destination files if they can’t be opened.
In other words, cp –remove-destination ensures an exact copy of the source file without being affected by the content of the destination files.
To confirm this behavior, we again use the stat command for two different files named file4.txt and file5.txt:
$ stat file4.txt file5.txt
File: file4.txt
Inode: 1184576
Access: (0664/-rw-rw-r--)
Access: 2024-01-15 21:19:32.673142483 +0500
Modify: 2024-01-15 21:19:32.673142483 +0500
Change: 2024-01-15 21:19:32.673142483 +0500
Birth: 2024-01-15 21:19:32.673142483 +0500
File: file5.txt
Inode: 1184577
Access: (0444/-r--r--r--)
Access: 2024-01-15 21:19:32.673142483 +0500
Modify: 2024-01-15 21:19:32.673142483 +0500
Change: 2024-01-18 01:48:37.481003393 +0500
Birth: 2024-01-15 21:19:32.673142483 +0500
Now, let’s use the cp –remove-destination command to copy the content of file1.txt to file4.txt and file5.txt:
$ cp --remove-destination file1.txt file4.txt
$ cp --remove-destination file1.txt file5.txt
Again, we use the stat command to check the metadata for both files:
$ stat file4.txt file5.txt
File: file4.txt
Inode: 1184573
Access: (0664/-rw-rw-r--)
Access: 2024-01-18 01:51:54.762761512 +0500
Modify: 2024-01-18 01:51:54.762761512 +0500
Change: 2024-01-18 01:51:54.762761512 +0500
Birth: 2024-01-18 01:51:54.762761512 +0500
File: file5.txt
Inode: 1184575
Access: (0664/-rw-rw-r--)
Access: 2024-01-18 01:51:59.958910895 +0500
Modify: 2024-01-18 01:51:59.958910895 +0500
Change: 2024-01-18 01:51:59.958910895 +0500
Birth: 2024-01-18 01:51:59.958910895 +0500
We can see that the metadata information of both files has been changed which indicates that both files have been deleted and replaced with new ones.
Thus, the –remove-destination switch disregards the current files at the destination, removing them completely before inserting the source files.
5. Conclusion
In this article, we discussed the standard cp command and its -f and –remove-destination options.
First, we saw that cp only copies files if the write permission for the destination files is available. Otherwise, we get the permission denied error. On the other hand, the cp -f command treats files the same as cp when we’ve got the write permission. Alternatively, it replaces the files with the new ones without worrying about permissions or conflicts.
Lastly, the cp –remove-destination command deletes the files regardless of the write permission and copies the content by creating a new file.