Linux Commands – cp
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In the last blog post, we have discussed mv command in Linux which is used to move/rename files and directories in Linux.
https://cloudaffaire.com/linux-commands-mv/
In this blog post, we will discuss cp command in Linux. cp stands for copy and is used to copy files and directories from the source location to the destination location.
Linux Commands – cp:
You can copy files and directories using cp command. You need to provide the full or relative path of the files/directories of source and destination. In order to copy directories, you need to use cp -R or -r or –recursive which copies directories recursively.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
######################### ## Linux Commands | cp ## ######################### ## Prerequisites: One Unix/Linux/POSIX-compliant operating system with bash shell ##--- ## cp ##--- ## cp [option]... [-T] source destination ## cp [option]... source... directory ## cp [option]... -t directory source... mkdir linuxcmd && cd linuxcmd ## create four file and directory mkdir mydir{1..4} touch myfile{1..4} ls cp myfile1 mydir1 ## copy myfile1 inside mydir1 ls mydir1 ## returns myfile1 cp mydir3 mydir4 ## not works cp -r mydir3 mydir4 ## copy mydir3 recursively inside mydir4 ls mydir4 ## returns mydir3 cp mydir1/myfile1 mydir4/mydir3 ## copy myfile1 from mydir1 to mydir3 ls mydir4/mydir3 ## returns myfile1 rm -r my* |
You can copy multiple files and directories at once using cp command. The last parameter will be treated as destination in this case. If the source files or directories have a common pattern, then you can also use regular expression with cp command.
1 2 3 4 5 6 7 8 9 10 |
mkdir mydir{1..3} ## create some files and directories touch myfile{1..3} mkdir ourdir ls cp -r mydir1 mydir2 mydir3 ourdir ## copy multiple directories at once, mv mydir* ourdir will also work cp myfile* ourdir ## uses regular expression * ls ourdir rm -r ourdir my* |
If the destination file/directory already exists, cp command overwrites the destination file/directory with the source file/directory. If destination file/directory does not exist, cp command copies the source file/directory to the destination file/directory.
1 2 3 4 5 6 7 8 9 10 11 12 |
mkdir -p mydir1 mydir/mydir1 ## create some files and directories echo "one" > myfile1 echo "two" > mydir/myfile1 echo "three" > mydir1/myfile1 echo "four" > mydir/mydir1/myfile1 cat mydir/mydir1/myfile1 ## returns four cp -r mydir1 mydir ## overwrites mydir1 and its content inside mydir with mydir1 and its content cat mydir/mydir1/myfile1 ## returns three cat mydir/myfile1 ## returns two cp myfile1 mydir ## overwrites myfile1 inside mydir with source myfile1 cat mydir/myfile1 ## returns one |
You can use cp -i or –interactive option to prompt before overwrite (overrides -n option)
1 2 3 4 |
cat mydir/mydir1/myfile1 ## returns three cp -i myfile1 mydir/mydir1/ ## -i causes one prompt before overwrite ## cp: overwrite ‘mydir/mydir1/myfile1’? y cat mydir/mydir1/myfile1 ## returns one |
You can use cp -n or –no-clobber option for not overwriting destination file if its exist. (overrides a previous -i option)
1 2 3 4 |
cat mydir1/myfile1 ## returns three cp -n myfile1 mydir1/myfile1 ## does nothing since myfile1 already exist inside mydir1 cat mydir1/myfile1 ## returns three rm -r my* |
You can use cp -f or –force option to forcefully copy and replace the destination file if the destination file cannot be opened (redundant if the -n option is used).
1 2 3 4 5 6 7 8 |
mkdir mydir ## create some files and directories touch myfile mydir/myfile chmod 444 mydir/myfile cp myfile mydir ## error, Permission denied cp -f myfile mydir ## successfull rm -r my* |
You can use cp –remove-destination option to remove each existing destination file before attempting to open it (contrast with –force).
1 2 3 4 5 6 7 8 |
mkdir mydir ## create some files and directories touch myfile mydir/myfile chmod 444 mydir/myfile cp myfile mydir ## error, Permission denied cp --remove-destination myfile mydir ## Successfull rm -r my* |
You can use cp -b option to take a backup of each existing destination file.
1 2 3 4 5 6 7 8 9 |
mkdir mydir1 mydir2 ## create some files and directory echo "one" > mydir1/myfile1 echo "two" > mydir2/myfile1 cp -b mydir1/myfile1 mydir2 ## creates a backup (myfile1~) of myfile1 before overwriting cat mydir2/myfile1~ ## returns two cat mydir2/myfile1 ## returns one rm -r my* |
You can use cp –backup[=CONTROL] option to take a backup of each existing destination file. CONTROL can be none (Never make backups), numbered or t (Make numbered backups), existing or nil (Numbered if numbered backups exist, simple otherwise) and simple or never (Always make simple backups).
1 2 3 4 5 6 7 8 9 10 11 12 |
mkdir mydir1 ## create some files and directory echo "one" > mydir1/myfile1 echo "two" > myfile1 cp --backup=t myfile1 mydir1 ## creates a backup (myfile1.~1~) of myfile1 before overwriting echo "three" > myfile1 cp --backup=t myfile1 mydir1 ## creates a backup (myfile1.~1~) of myfile1 before overwriting cat mydir1/myfile1 ## returns three cat mydir1/myfile1.~1~ ## returns one cat mydir1/myfile1.~2~ ## returns two rm -r my* |
You can overwrite the usual backup suffix (~) with cp -S or –suffix=SUFFIX option.
1 2 3 4 5 6 7 8 9 |
mkdir mydir1 ## create some files and directory echo "one" > mydir1/myfile1 echo "two" > myfile1 cp --suffix=.bak myfile1 mydir1 ## creates a backup (myfile1.bak) of myfile1 before overwriting cat mydir1/myfile1 ## returns two cat mydir1/myfile1.bak ## returns one rm -r my* |
You can get details of what cp command is doing using cp -v or –verbose options.
1 2 3 4 5 6 7 8 9 10 11 |
touch myfile{1..3} ## create some files and directories mkdir mydir cp -v myfile* mydir ## returns ## ‘myfile1’ -> ‘mydir/myfile1’ ## ‘myfile2’ -> ‘mydir/myfile2’ ## ‘myfile3’ -> ‘mydir/myfile3’ rm -r my* |
You can also use cp -u or –update options to copy only when the SOURCE file is newer than the destination file or when the destination file is missing.
1 2 3 4 5 6 7 8 9 |
mkdir mydir{1,2} ## create some files and directories echo "one" > mydir1/myfile1 cp -v mydir1/myfile1 mydir2/ ## myfile1 will be copied from mydir1 to mydir2 cp -uv mydir1/myfile1 mydir2/ ## does nothing echo "two" > mydir1/myfile1 cp -uv mydir1/myfile1 mydir2/ ## myfile1 will be copied from mydir1 to mydir2 rm -r my* |
You can use cp -s or –symbolic-link option to make symbolic links instead of copying.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
echo "one" > myfile1 ## create some files and directories mkdir -p mydir1/mydir2 echo "two" > mydir1/mydir2/myfile2 cp -sv myfile1 mylink1 ## create a symbolick link mylink1, ‘myfile1’ -> ‘mylink1’ ls -l ## -rw-rw-r-- 1 user user 4 May 14 04:34 myfile1 ## lrwxrwxrwx 1 user user 7 May 14 04:34 mylink1 -> myfile1 pwd ## /home/user/mydir cp -sv /home/user/mydir/mydir1/mydir2/myfile2 mylink2 ## create a symbolic link ls -l ## drwxrwxr-x 3 user user 20 May 14 04:34 mydir1 ## -rw-rw-r-- 1 user user 4 May 14 04:34 myfile1 ## lrwxrwxrwx 1 user user 7 May 14 04:34 mylink1 -> myfile1 ## lrwxrwxrwx 1 user user 41 May 14 04:34 mylink2 -> /home/user/mydir/mydir1/mydir2/myfile2 rm -r my* |
You can use cp -H option to follow command-line symbolic links in SOURCE. If a command-line argument specifies a symbolic link, then copy the file it points to rather than the symbolic link itself. However, copy (preserving its nature) any symbolic link that is encountered via recursive traversal.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mkdir -p mydir1/mydir11 mydir2 ## create some files and directories ln -s mydir1 mylink1 echo "one" > mydir1/myfile1 echo "two" > mydir1/mydir11/myfile11 cd mydir1 ln -s mydir11 mylink11 ## create a symbolic link mylink11 pointing to mydir11 cd .. ls -R ## check directory structure, you can use tree as well cp -RH mylink1 mydir2 ## follows command-line symbolic links in SOURCE ls -R ## check directory structure, you can use tree as well rm -r my* |
Use cp -L or –dereference options to always follow symbolic links in SOURCE instead of creating one. With this option, ‘cp’ cannot create a symbolic link.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mkdir -p mydir1/mydir11 mydir2 ## create some files and directories ln -s mydir1 mylink1 echo "one" > mydir1/myfile1 echo "two" > mydir1/mydir11/myfile11 cd mydir1 ln -s mydir11 mylink11 ## create a symbolic link mylink11 pointing to mydir11 cd .. ls -R ## check directory structure, you can use tree as well cp -RL mylink1 mydir2 ## follows command-line symbolic links in SOURCE ls -R ## check directory structure, you can use tree as well rm -r my* |
Use cp -P or –no-dereference options to never follow symbolic links in SOURCE.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mkdir -p mydir1/mydir11 mydir2 ## create some files and directories ln -s mydir1 mylink1 echo "one" > mydir1/myfile1 echo "two" > mydir1/mydir11/myfile11 cd mydir1 ln -s mydir11 mylink11 ## create a symbolic link mylink11 pointing to mydir11 cd .. ls -R ## check directory structure, you can use tree as well cp -RP mylink1 mydir2 ## never follows symbolic links in SOURCE ls -R ## check directory structure, you can use tree as well rm -r my* |
Use cp -l or –link options to make hard links instead of copies of non-directories.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mkdir mydir{1,2} ## create some file and directories echo "one" > myfile cp -l myfile mydir1 ## Inode remains the same as hard link is created cp myfile mydir2 ## Inode changes as copy of the original ls -li myfile ## 4600696 -rw-rw-r-- 1 user user 4 May 14 05:54 myfile ls -li mydir1/myfile ## 4600696 -rw-rw-r-- 2 user user 4 May 14 05:54 mydir1/myfile ls -li mydir2/myfile ## 57526 -rw-rw-r-- 1 user user 4 May 14 05:59 mydir2/myfile rm -r my* |
Generally, when you copy a file, the file attributes may get changed during the copy. You can use cp –preserve[=ATTR_LIST] to preserve the specified attributes (default: mode,ownership,timestamps), if possible additional attributes: context, links, xattr, all.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
echo "hello" > myfile ## Create some files and directories mkdir mydir ls -l myfile ## returns -rw-r--r-- 1 user user 6 May 14 19:45 myfile cp myfile mydir ls -l mydir/myfile ## returns -rw-r--r-- 1 user 197121 6 May 14 19:48 myfile ## observe the timestamp has changed, timestamp is one of the file attributes ## for simplicility we will only preserve the timestamp ## but other supported attributes can also be preserved. cp --preserve=timestamps myfile mydir/myfile ls -l mydir/myfile ## returns -rw-r--r-- 1 user 197121 6 May 14 19:45 mydir/myfile ## timestamp remains the same. rm -r my* |
You can also use cp -p (same as –preserve=mode,ownership,timestamps) to preserve the source attributes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
echo "hello" > myfile ## Create some files and directories mkdir mydir ls -l myfile ## returns -rw-r--r-- 1 user user 6 May 14 19:52 myfile cp myfile mydir ls -l mydir/myfile ## returns -rw-r--r-- 1 user 197121 6 May 14 19:54 mydir/myfile ## observe the timestamp has changed, timestamp is one of the file attributes ## for simplicility we will only preserve the timestamp ## but other supported attributes can also be preserved. cp -p myfile mydir/myfile ls -l mydir/myfile ## returns -rw-r--r-- 1 user 197121 6 May 14 19:52 mydir/myfile ## timestamp remains the same. rm -r my* |
You can also use cp -a or –archive options (same as -dR –preserve=all) to archive the source. cp –no-preserve=ATTR_LIST option does the opposite of this command.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
echo "hello" > myfile ## Create some files and directories mkdir mydir ls -l myfile ## returns -rw-r--r-- 1 user user 6 May 14 19:55 myfile cp myfile mydir ls -l mydir/myfile ## returns -rw-r--r-- 1 user 197121 6 May 14 19:57 mydir/myfile ## observe the timestamp has changed, timestamp is one of the file attributes ## for simplicility we will only preserve the timestamp ## but other supported attributes can also be preserved. cp -a myfile mydir/myfile ls -l mydir/myfile ## returns -rw-r--r-- 1 user 197121 6 May 14 19:55 mydir/myfile ## timestamp remains the same. rm -r my* |
You can use cp –parents option to copy full source file name under DIRECTORY.
1 2 3 4 5 6 7 8 9 |
mkdir -p mydir1/mydir11 mydir2 ## creates some files and directories touch mydir1/mydir11/myfile cp mydir1/mydir11/myfile mydir2 ## copies myfile to mydir2 ls mydir2 cp --parents mydir1/mydir11/myfile mydir2 ## copies mydir1/mydir11/myfile to mydir2 ls mydir2 rm -r my* |
You can use cp –strip-trailing-slashes option to remove any trailing slashes from each SOURCE argument.
1 2 3 4 5 6 7 8 9 10 |
mkdir mydir{1,2} ## creates some files and directories cp -rv mydir1/ mydir2/ ## 'mydir1/' -> 'mydir2/mydir1' ## source trailing slash ('mydir1/') is interpreted rm -r my* mkdir mydir{1,2} cp -rv --strip-trailing-slashes mydir1/ mydir2/ ## 'mydir1' -> 'mydir2/mydir1' ## source trailing slash ('mydir1') is not interpreted rm -r my* |
You can use cp –sparse=WHEN control copy a sparse file. By default, cp supports sparse file copy but the source file system should support sparse file. The cp –sparse=always is useful when the source does not support sparse files but has a long sequence of zero in it and the target file system supports sparse files.
1 2 3 4 5 6 7 |
## Create a sparse file dd if=/dev/zero of=myfile1 bs=1 count=0 seek=10M cp --sparse=never myfile1 myfile2 ## copy the sparse file ls -lhs myfile1 myfile2 rm my* |
You can use cp -t or –target-directory=DIRECTORY to copy all SOURCE arguments into DIRECTORY.
1 2 3 4 5 6 7 8 |
mkdir mydir{1,2} ## create some files and directories touch mydir1/myfile.{sh,txt,zip,tar} find mydir1/ -type f -name "*.t*" | xargs cp mydir2 ## does not works ## cp: target ‘mydir1/myfile.tar’ is not a directory find mydir1/ -type f -name "*.t*" | xargs cp -t mydir2 ## works with -t option rm -r my* |
You can use mv -T or –no-target-directory treat DEST as a normal file.
1 2 3 4 5 6 7 8 9 |
echo "one" > myfile1 ## create some files and directories echo "two" > mydir1 mkdir -p mydir/mydir1 cp -T myfile1 mydir/mydir1 ## mydir1 is treated as a file ## cp: cannot overwrite directory ‘mydir/mydir1’ with non-directory cp -R myfile1 mydir/mydir1 ## mydir1 is treated as a directory rm -r my* |
Hope you have enjoyed this article. If an option is left, kindly give a demo in the comment and I will include that in this article. In the next blog post, we will discuss echo command in Linux.