Course outline · 0% complete

0/29 lessons0%

Course overview →

Copying and moving: cp and mv

lesson 3-2 · ~10 min · 8/29

cp copies, mv moves AND renames

These two are the workhorses of file organization: back up a config file before you edit it, pull a download into the right project, fix a bad filename. You'll type them daily.

  • cp source destination: makes a copy. The original stays. For directories you need cp -r (r for recursive, meaning "and everything inside").
  • mv source destination: moves the file. The original is gone from its old place.

Here's the part beginners miss: renaming is just moving. mv old-name.txt new-name.txt "moves" the file to a new name in the same directory. There is no separate rename command in daily use.

Both commands overwrite the destination silently if it already exists, so read your command once before pressing Enter.

cp a.txt b.txta.txtb.txttwo files exist aftermv a.txt b.txta.txtb.txtonly one file exists after
cp leaves the original in place. mv takes it away, which is also how files get renamed.

Copy, then rename, and see what survives

This example writes a file, copies it to a backup, then renames the original. ls shows which names exist afterwards, and cat proves the backup kept the text.

echo "draft one" > essay.txt
cp essay.txt backup.txt
mv essay.txt final.txt
ls
cat backup.txt

Output

backup.txt
final.txt
draft one

Notice what is missing from the listing. After the mv, essay.txt no longer exists, so ls reports only backup.txt and final.txt. The content itself was never touched by either command, which is why cat backup.txt still prints the original draft one.

Why directories need cp -r

Plain cp refuses a directory, because copying a directory means copying everything inside it, and -r (recursive) is how you say that is what you want. The resulting backup contains the same tree as the original.

mkdir -p project/src
echo "print('hi')" > project/src/main.py
cp -r project project-backup
ls project-backup
ls project-backup/src

Output

src
main.py

The two ls calls walk down the copy to prove it is complete: project-backup contains src, and src contains main.py. Without -r, cp would decline the job and print an error about omitting a directory rather than copying anything.

Running mv notes.txt notes-old.txt inside one directory renames the file. Afterwards only notes-old.txt exists, and its content is unchanged.

The reason is that mv moves a file to a new path, and a different name in the same directory is simply a different path. The old name disappears, the bytes stay exactly as they were, and the visible effect is a rename. That is why Linux needs no separate rename command for everyday work.

To rename notes.txt to ideas.txt, the command is mv notes.txt ideas.txt.

cp notes.txt ideas.txt would also produce a file called ideas.txt, but it leaves notes.txt sitting there as well, so the result is two files rather than a rename. When the goal is for the old name to stop existing, mv is the command that does it.

Both commands accept a destination in another directory, which lets one short session copy a file elsewhere and rename the original. Here cp plan.txt safe/plan-copy.txt places a copy inside safe/ under a new name, and mv plan.txt renamed-plan.txt renames what is left behind.

mkdir safe
echo "top secret" > plan.txt
cp plan.txt safe/plan-copy.txt
mv plan.txt renamed-plan.txt
ls
ls safe

Output

renamed-plan.txt
safe
plan-copy.txt

The two listings explain the three output lines. The first ls shows the working directory, which now holds renamed-plan.txt and the safe directory, with no trace of plan.txt. The second ls safe looks inside that directory and finds the copy, plan-copy.txt.