---
title: 'Creating, Copying, and Moving'
source: 'https://academia.sh/en/courses/introduction-to-linux/creating-copying-and-moving'
course: 'Introduction to Linux'
language: en
updated: '2026-08-17T18:09:55+00:00'
license: 'CC BY-SA 4.0'
---

# Creating, Copying, and Moving

Creating files and setting timestamps, copying's overwrite behavior, the case where the target is a directory, and what moving means at the file system level.

The previous lesson made the tree readable, but the `data/raw` directory was empty.
This lesson fills the tree: measurement files are created, processed copies are
produced, and a backup directory is set up.

Three commands will be used — `touch`, `cp`, `mv` — and all three have situations
where they silently lose data. Which rules give rise to these situations matters more
than the commands themselves.

## Creating Files and Timestamps

The `touch` command's real job is setting timestamps; creating an empty file when
given a name that does not exist is a secondary behavior.

```
$ touch data/raw/measurement-01.csv
$ ls -l data/raw
total 0
-rw-r--r-- 1 student student 0 Jul 26 19:02 measurement-01.csv
```

The size is zero: the file exists but has no content. A file existing and a file
having content are separate things; a directory entry and an inode have been
created, but no data block has been allocated.

Output redirection is used to write content:

```
$ printf 'zaman,sicaklik,nem\n08:00,21.4,55\n12:00,24.9,49\n' > data/raw/measurement-01.csv
$ cat data/raw/measurement-01.csv
zaman,sicaklik,nem
08:00,21.4,55
12:00,24.9,49
```

The `>` sign writes the command's output to a file instead of the terminal. The
grammar of redirection is the subject of the Shell Programming course; here it is
used only to produce a file. The point to note is this: `>` **empties the target file
without warning**. Writing to an existing file with `>` deletes the old content
irreversibly.

Two more measurement files are created the same way:

```
$ printf 'zaman,sicaklik,nem\n08:00,19.8,61\n12:00,23.1,52\n' > data/raw/measurement-02.csv
$ printf 'zaman,sicaklik,nem\n08:00,22.6,58\n12:00,26.3,44\n' > data/raw/measurement-03.csv
$ ls -l data/raw
total 12
-rw-r--r-- 1 student student 47 Jul 26 19:02 measurement-01.csv
-rw-r--r-- 1 student student 47 Jul 26 19:03 measurement-02.csv
-rw-r--r-- 1 student student 47 Jul 26 19:03 measurement-03.csv
```

On an existing file, `touch` does not touch the content, it only sets the timestamps
to that moment. To set a specific time, the `-t` option is used:

```
$ touch /tmp/sample.txt
$ ls -l /tmp/sample.txt
-rw-r--r-- 1 student student 0 Jul 26 19:03 /tmp/sample.txt
$ touch -t 202603110930 /tmp/sample.txt
$ ls -l /tmp/sample.txt
-rw-r--r-- 1 student student 0 Mar 11 09:30 /tmp/sample.txt
```

The `-t` value is in `YYYYMMDDhhmm` format and is defined in POSIX. The `-d` option
in GNU tools accepts human-readable date strings but is not portable; `-t` is
preferred in scripts.

Setting a timestamp is not just a matter of tidiness: most backup and build tools do
an "is the source newer than the target" comparison, and this comparison relies on
the modification time.

## Copying

The `cp` command takes two arguments: source and target. Two different rules apply
depending on what the target is.

**If the target is an existing directory**, the source is copied into it, **under
the same name**:

```
$ cp data/raw/measurement-01.csv data/processed/
$ ls -l data/processed
total 4
-rw-r--r-- 1 student student 47 Jul 26 19:03 measurement-01.csv
```

**If the target is not a directory**, the source is copied under that name:

```
$ cp data/raw/measurement-01.csv data/processed/summary-01.csv
$ ls -l data/processed
total 8
-rw-r--r-- 1 student student 47 Jul 26 19:03 measurement-01.csv
-rw-r--r-- 1 student student 47 Jul 26 19:03 summary-01.csv
```

These two rules are the source of the most common mistake: if the target directory's
name is misspelled, the directory is not found, and the command creates the copy
**as a file under that wrong name**. No error message appears. Putting a slash at
the end of the target catches this mistake: when `targetdir/` is written and no such
directory exists, the command gives an error.

## Overwriting Is Silent

By default, `cp` writes over the target without asking:

```
$ cat data/processed/summary-01.csv
zaman,sicaklik,nem
08:00,21.4,55
12:00,24.9,49
$ cp data/raw/measurement-02.csv data/processed/summary-01.csv
$ cat data/processed/summary-01.csv
zaman,sicaklik,nem
08:00,19.8,61
12:00,23.1,52
```

The old content is gone and cannot be brought back. There is no warning, and the
exit status is zero.

The `-i` option asks before overwriting:

```
$ cp -i data/raw/measurement-03.csv data/processed/summary-01.csv
cp: overwrite 'data/processed/summary-01.csv'? n
```

On a negative answer, the file does not change, and the command returns a non-zero
exit status. `-i` is defined in POSIX and is the recommended habit for interactive
use.

There is also an option to protect an existing target without asking at all, but it
is not portable; in GNU tools, when `-n` is given, a warning is printed that this
option's behavior may change. In scripts, the target's existence is tested first;
the option is not relied on.

## Copying Directories

Directories are not copied by default; `-r` is needed for recursive copying.

```
$ cp -r data/raw archive/raw-backup
$ ls -l archive/raw-backup
total 12
-rw-r--r-- 1 student student 47 Jul 26 19:04 measurement-01.csv
-rw-r--r-- 1 student student 47 Jul 26 19:04 measurement-02.csv
-rw-r--r-- 1 student student 47 Jul 26 19:04 measurement-03.csv
```

Copies are new files: a new inode, a new timestamp. If the timestamps should be
preserved, `-p` is added:

```
$ cp -rp data/raw archive/raw-p
$ ls -l archive/raw-p
total 12
-rw-r--r-- 1 student student 47 Jul 26 19:02 measurement-01.csv
-rw-r--r-- 1 student student 47 Jul 26 19:03 measurement-02.csv
-rw-r--r-- 1 student student 47 Jul 26 19:03 measurement-03.csv
```

Comparing the two listings, the difference is clear: without `-p` all files carry
the moment of copying, with `-p` they keep their original times. `-p` also tries to
preserve permissions and ownership. This detail is decisive in backups; a backup
that has lost its timestamps cannot answer the question "which version is newer."

In directory copying, the target rule turns into a trap:

```
$ cp -r /tmp/demo/source /tmp/demo/target
$ find /tmp/demo | sort
/tmp/demo
/tmp/demo/target
/tmp/demo/target/source
/tmp/demo/target/source/a.txt
/tmp/demo/source
/tmp/demo/source/a.txt
```

If the target directory **already exists**, the source is placed inside it. When
the same command is run a second time, the result does not change, because
`target/source` now exists too and the content is overwritten. But if it is run
while the target does not exist, the target is created as a copy of the source. The
same command giving two different results depends on whether the target existed
beforehand.

## Moving

`mv` looks like copying on the surface, but at the file system level it is an
entirely different operation.

```
$ ls -li data/processed
total 8
22212 -rw-r--r-- 1 student student 47 Jul 26 19:03 measurement-01.csv
22545 -rw-r--r-- 1 student student 47 Jul 26 19:03 summary-01.csv
$ mv data/processed/summary-01.csv data/processed/daily-summary.csv
$ ls -li data/processed
total 8
22545 -rw-r--r-- 1 student student 47 Jul 26 19:03 daily-summary.csv
22212 -rw-r--r-- 1 student student 47 Jul 26 19:03 measurement-01.csv
```

The inode number has not changed: `22545` is the same under both the old and new
name. The only thing that changed is **the directory entry**. The name is not a
property of the file; it is a mapping kept in the directory. Changing the name does
not touch the file.

The measurable consequence of this is that moving within the same file system has
constant cost, independent of file size. Renaming a one-byte file and a
one-gigabyte file takes the same time, because no data is read or written.

This does not hold when the same operation is done between different file systems.
Inode numbers are meaningful only within their own file system; an entry cannot be
carried from one device to another. In this case `mv` copies the content and
deletes the source — the time is proportional to file size, and if the operation is
interrupted midway, the target can be left incomplete.

If the target is a directory, `mv` follows the same naming rule too:

```
$ mv data/processed/measurement-01.csv docs/
$ ls docs
measurement-01.csv
$ ls data/processed
daily-summary.csv
```

`mv` also overwrites silently, and the `-i` option makes it ask. Unlike copying,
here two files are lost at once: the target's old content is deleted, and the
source disappears too.

## Summary

- `touch` sets timestamps; creating a nonexistent file as empty is a secondary
  behavior, and a specific time can be given with `-t`.
- In copying, if the target is an existing directory, the source is copied into it
  under the same name; otherwise it is copied under the given name. A misspelled
  directory name silently creates a file.
- `cp` and `mv` write over the target without asking; `-i` makes them ask.
- Copying a directory requires `-r`; `-p` preserves timestamps, permissions, and
  ownership.
- Moving within the same file system changes only the directory entry: the inode
  number is preserved, and the cost is independent of file size.
- Moving between different file systems turns into a copy-and-delete operation; the
  cost is proportional to size and carries the risk of being interrupted midway.

## Next Step

All three commands in this lesson can lose data, but each does it by overwriting
something. The deletion command, on the other hand, destroys directly, and the file
system has no "undo" operation. The next lesson takes up what deletion means at the
kernel level, under what condition a deleted file is still alive, and how to make
verification a habit before running destructive commands.
