Learn › Linux Foundations › Manipulation
cp - a hands-on Linux lab on a real virtual machine.
Copy files and folders with cp. It is silent on success, so every drill runs cp then proves the result with ls or cat. Learn the core cp source dest shape, -v to watch the copy, -r for whole folders, copying a file into a folder, -i to guard overwrites, and -p to clone permissions and timestamps, plus the three errors cp actually prints.
You have a file called notes.txt. You are about to change it, and you are nervous, because there is no undo button on a terminal. So before you touch it, you want a spare, an identical second copy you can fall back on if the edit goes wrong.
The command for that is cp, short for copy. Type it, press Enter, and something strange happens: nothing. No output, no confirmation, just a fresh prompt. That silence is not failure. It is cp telling you, in the quietest way possible, that the copy is already made. This lesson teaches you to trust that silence, and to prove the copy landed with your own eyes.
The black boxes below are a practice terminal: a safe sandbox that checks the one command each step teaches, so you cannot break anything. Because cp prints nothing when it succeeds, every drill runs cp and then runs a second command, like ls, that DOES print, so you can see the copy really appeared. The outputs shown are exactly what a stock Linux machine produces.
cp makes a copy of a file. You give it two things: the file to copy FROM, called the source, and the name to copy it TO, called the destination. The shape is always cp source destination. The source is left untouched; a new file appears at the destination.
Think of it like a photocopier. You feed in one page, the original slides back out unchanged, and a fresh duplicate drops into the tray. cp notes.txt backup.txt reads notes.txt, leaves it exactly as it was, and creates a brand new backup.txt with the same contents.
cp is one of the original Unix commands, in the toolkit since 1971. The two-letter name is deliberate: the people who built Unix typed these words hundreds of times a day, so they made the ones they used most as short as possible. cp, mv, rm, ls. A whole workflow in two keystrokes each.
Here is the core move. You have a file notes.txt, and you want a duplicate named backup.txt. You run cp, see nothing, and then run ls to list the folder and watch both files sit there side by side.
Before you run it, decide what you expect: after the copy, how many files should ls show? You started with one. A copy adds a second. So ls should list two.
cp notes.txt backup.txt
prompt: student@linuxcamp:~$ answer: cp notes.txt backup.txt output: hint: Type cp, a space, the source notes.txt, a space, then the new name backup.txt: cp notes.txt backup.txt
Nothing printed, and that is the success. cp never announces a copy that worked. To SEE the result, you list the folder. Run ls now and you get backup.txt notes.txt, both present. The original notes.txt is untouched, and backup.txt is a full duplicate of it. That is the whole idea of cp: one command in, two files out, and silence in between. From here on, every time you copy, your instinct should be the same: run cp, then run ls or cat to confirm with your own eyes.
That silence is efficient, but when you are learning, or copying a long list of files, you want to SEE each copy as it happens. The -v flag does that. -v stands for verbose, which just means talkative. With -v, cp prints one line for every file it copies, in the form source -> dest.
This is the one form of cp that prints on success. Copy notes.txt to copy2.txt and watch cp narrate the move:
cp -v notes.txt copy2.txt
prompt: student@linuxcamp:~$ answer: cp -v notes.txt copy2.txt output: 'notes.txt' -> 'copy2.txt' hint: Add the -v flag right after cp: cp -v notes.txt copy2.txt
There it is: 'notes.txt' -> 'copy2.txt'. The arrow reads left to right, from source to destination, exactly the order you typed them. This is the same copy cp made silently before; -v just narrates it out loud. When you copy many files at once, -v turns an invisible operation into a running list you can watch and check. Everything to the left of the arrow is what was read; everything to the right is what was written.
So far you have copied single files. Try to copy a whole folder the same way and cp stops you cold. A folder holds other files and folders inside it, and cp refuses to copy that whole tree unless you say you mean it.
The way you say you mean it is the -r flag. -r stands for recursive, which means go into the folder and copy everything inside it, all the way down. You have a folder named project, and you want a full duplicate named project-copy. The -r flag makes cp copy the folder and its entire contents:
cp -r project project-copy
prompt: student@linuxcamp:~$ answer: cp -r project project-copy output: hint: Add -r so cp will descend into the folder: cp -r project project-copy
Silent again, and again that means it worked. Run ls and you now see both project and project-copy sitting next to each other, and every file that was inside project is inside project-copy too. The -r flag is what made the difference: without it, cp would have refused and printed an error (you will meet that error in a moment). The rule to carry away is simple: single files copy on their own, but a folder always needs -r. Some machines print the flag as -R; both do the same job.
There is a second everyday shape you will reach for constantly. Instead of giving cp a new filename to write, you give it an existing FOLDER as the destination. cp then drops the file inside that folder, keeping its original name.
You have a file notes.txt and a folder project. Copy the file into the folder. The trailing slash on project/ is a small habit worth keeping: it makes it clear to you, and to the reader, that the destination is a folder:
cp notes.txt project/
prompt: student@linuxcamp:~$ answer: cp notes.txt project/ output: hint: The destination is the folder name with a slash: cp notes.txt project/
Silent success once more. To prove it, look INSIDE the folder with ls project/, and you will see notes.txt now living there. The original notes.txt is still in your current folder too, because cp copies, it never moves. This is the pattern you use to gather files into a folder: point cp at the file, then at the folder, and the file lands inside with its name intact. Notice you did not give a new name; when the destination is a folder, cp keeps the source's own name.
Here is the sharp edge of cp. If the destination file already exists, cp overwrites it without asking. The old contents are gone, silently, with no warning. That is how a careless copy erases the very backup you were trying to protect.
The -i flag is the seatbelt. -i stands for interactive, and it makes cp stop and ASK before it overwrites anything that already exists. You answer y to allow it or n to cancel. Try to copy notes.txt onto the backup.txt you already made, with -i guarding you:
cp -i notes.txt backup.txt
prompt: student@linuxcamp:~$ answer: cp -i notes.txt backup.txt output: cp: overwrite 'backup.txt'? hint: Add -i so cp asks before it clobbers an existing file: cp -i notes.txt backup.txt
Instead of silently replacing backup.txt, cp paused and asked cp: overwrite 'backup.txt'?. Type y and Enter to go ahead, or n and Enter to back out with the original safe. That one prompt is the difference between a controlled copy and an accidental erase. Many careful engineers make -i the default, so cp always asks before it clobbers. When you are copying over files that matter, reach for -i first.
A plain cp copies the CONTENTS of a file, but it stamps the new copy with the current time and your default permissions. Sometimes you need a true clone: same contents, same permissions, and the same original timestamps. That is what -p gives you. -p stands for preserve, and it keeps the mode (the permissions), the owner, and the timestamps of the source.
Copy notes.txt to archive.txt preserving everything, then use ls -l (the long listing that shows permissions and dates) to see that the details carried over:
cp -p notes.txt archive.txt
prompt: student@linuxcamp:~$ answer: cp -p notes.txt archive.txt output: hint: Add -p to preserve permissions and timestamps: cp -p notes.txt archive.txt
Silent, as always. Now run ls -l notes.txt archive.txt and compare the two rows: the permissions and the timestamp on archive.txt match notes.txt exactly, instead of showing the moment you ran the copy. Without -p, that timestamp would read now, and the permissions would fall back to your defaults. -p is what you use when the copy must be indistinguishable from the original, not just same-contents but same-everything. There is a bigger cousin, -a for archive, which is -r and -p together for cloning whole folders faithfully.
Scaffolding off. No command is printed this time. You have every piece you need.
You are about to edit an important file called config.txt, and you want a safety copy before you touch it. Make an exact duplicate named config.txt.bak in the same folder. Contents only; a plain copy is all this asks for.
prompt: student@linuxcamp:~$ answer: cp config.txt config.txt.bak output: hint: Same shape you used all lesson: cp, the source file, then the new backup name. Think cp config.txt config.txt.bak
Nothing printed, which is exactly right. You typed cp config.txt config.txt.bak from memory: source first, new name second, and cp made the duplicate in silence. To confirm it on a real machine you would run ls and see both config.txt and config.txt.bak. Making a .bak copy before editing is one of the most common moves a working engineer makes all day, and you just did it without being shown the command.
cp is silent when it works, so when it DOES speak on an error, read the line carefully. Here are the three you will meet most, what each means, and what to check first.
First, copying a folder without -r:
cp: -r not specified; omitting directory 'project'
This means you tried to copy a folder but did not tell cp to go inside it. The fix: add the -r flag. Check first that the thing you are copying really is a folder, then rerun with cp -r.
Second, a source that does not exist:
cp: cannot stat 'notes.txt': No such file or directory
The word stat means cp tried to look up the file and could not find it. This is almost always a typo in the source name or being in the wrong folder. Check first with ls that the file is spelled exactly right and actually sits where you are standing.
Third, no permission to write the destination:
cp: cannot create regular file '/etc/hosts': Permission denied
This means the folder you are copying INTO does not allow you to write there. The fix is usually to copy somewhere you own, like your home folder, or to run the copy with elevated rights using sudo. Check first WHERE you are writing to, not the file you are reading from.
You earned this cheat sheet. Every row is a form of cp you just ran:
The one habit under all of it: cp says nothing when it works, so you never trust the silence blindly. You run cp, then you run ls, ls -l, or cat to prove the copy landed. Copy, then confirm.
cp always copies, it never moves. The original always stays put. When you want to MOVE a file instead, so the original does not remain, that is a different command, mv, and it is the very next lesson.
The practice terminal has shown you the whole of cp. You copy a file to a new name, watch it with -v, copy a folder with -r, drop a file into a folder, guard overwrites with -i, and clone every detail with -p. Above all, you learned to prove a silent copy with ls and cat. Every one of those you typed yourself.
The Manipulation module ends with one real Linux machine, the module capstone mission, and that is where you put these pieces to work for real. A VM boots just for you, with a live shell and real files to copy, move, and rename. It hands you objectives that use exactly what you practiced across this module. One difference from here: the mission shows no commands. You read the objective, you recall the command, you type it. That recall is what makes it stick.
Finish the other Manipulation lessons, then go copy real files on a real machine.
Practice cp in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.