42CodeLens

Shell00: files, permissions and the command line

Shell00 is the first module of the 42 Piscine, and it contains no C at all. It checks that you can operate a Unix system deliberately. This guide explains the concepts it relies on, with examples of its own — it does not give exercise answers.

What Shell00 asks of you

Each Shell00 exercise is answered either by a file — with exactly the right contents, name and permissions — or by a short command line saved in a file. Nothing is compiled. What the module is really teaching is precision: an answer that is almost right is wrong.

A few rules of thumb hold across the module (always check your own subject for the exact wording):

A file: name, bytes and metadata

On a Unix system a file is more than its contents. The filesystem keeps a record for each file — its type, permissions, owner, group, size, link count and several timestamps. A directory entry is just a name that points at that record. stat prints the whole record:

$ stat notes.txt
  File: notes.txt
  Size: 1204        Blocks: 8          IO Block: 4096   regular file
Access: (0644/-rw-r--r--)  Uid: ( 1000/   alice)   Gid: ( 1000/   alice)
Modify: 2026-03-03 10:15:42.000000000 +0100

(The exact layout differs between Linux and macOS — read the fields, not the formatting.) The size counts every byte, including the newline at the end of the last line, which is why echo hello writes six bytes, not five. The modification time changes when contents change; touch updates it, and can also set it to a chosen value (see man touch).

To see exactly what bytes a file holds, cat -e marks the end of every line with $, making missing or extra newlines visible. wc -c counts bytes; od -c shows every character, including invisible ones.

Permissions and chmod

Every file has three sets of permissions — for its user (owner), its group, and others — and each set has three bits: read (r), write (w) and execute (x). Written as octal, each set is one digit, the sum of read = 4, write = 2 and execute = 1:

DigitBitsMeaning
7rwxread, write and execute
6rw-read and write
5r-xread and execute
4r--read only
0---nothing

So chmod 640 report.txt gives the owner read and write, the group read, and others nothing — shown by ls -l as -rw-r-----. chmod also takes a symbolic form: chmod g+w report.txt adds write for the group and leaves every other bit alone.

On a directory the bits mean something different: r lets you list its names, w lets you create and remove entries in it, and x lets you enter it and reach the files inside. A directory you can read but not execute shows you names you cannot open.

New files do not start at 666 or 777: your umask removes bits from the default. That is why a fresh file is often -rw-r--r--. When an exercise specifies permissions, set them explicitly rather than trusting defaults.

Reading ls -l, field by field

ls -l prints one line per entry. Take this made-up line:

-rw-r-----  1 alice  staff  1204 Mar  3 10:15 report.txt

Some systems add a character after the permissions — @ for extended attributes on macOS, + for access control lists — and a total line at the top of a directory listing. Learn to recognise them so they do not surprise you.

ls has many options that change which entries appear, how they are sorted and how they are separated. When you need a particular output, read man ls, combine options, and check the result against what is asked — character by character.

A hard link is a second name for the same file record. Both names are equal: edit through one and the other shows the change, and the data survives until the last name is removed. Creating one increases the link count shown by ls -l.

$ ln report.txt report-copy.txt     # hard link: same file, two names
$ ln -s report.txt latest.txt       # symbolic link: a pointer to a path

A symbolic link is a small file of its own that holds a path. ls -l shows it with type l and an arrow to its target. If the target is moved or deleted, the link is left "dangling" and opening it fails. Symbolic links can point at directories and across filesystems; hard links, in general, cannot.

Archives with tar

tar packs files and directories into one archive file and unpacks them again. Crucially, it records metadata — permissions, timestamps, and the difference between a file and a link — which a plain copy through some tools would lose.

$ tar -cf backup.tar project/     # create an archive of a directory
$ tar -tvf backup.tar             # list its contents, verbosely
$ tar -xf backup.tar              # extract it

The verbose listing looks much like ls -l, which makes it the easiest way to check that an archive holds exactly what you think it does, with the metadata you intended.

SSH key pairs

SSH authentication with keys uses a pair: a private key that never leaves your machine, and a public key you can hand to any server or service. Something encrypted or signed with one can be checked with the other, so a server holding your public key can confirm you hold the private one without it ever being sent.

$ ssh-keygen -t ed25519 -C "my laptop"

This writes two files, by default in ~/.ssh/: the private key and the same name ending in .pub. Only the .pub file is ever shared. If a private key is exposed, generate a new pair and replace the public key wherever it was used.

Git: asking a repository questions

Your Piscine work is submitted through Git, so Shell00 makes sure you can ask a repository what it knows. Every commit has an identifier (a long hexadecimal hash), an author, a date and a message, and git log walks back through them:

$ git log --oneline        # one short line per commit
$ git status               # what changed, what is staged, what is untracked
$ git show HEAD            # the most recent commit in full

git log can print any combination of a commit's fields in a format you choose — see the "PRETTY FORMATS" section of man git-log.

A .gitignore file lists patterns for files Git should not track, such as build output or editor backups. Git can also tell you which files it is ignoring, and why; man git-status, man git-ls-files and man git-check-ignore are the places to look.

One thing worth knowing early: Git stores file contents and the executable bit, but not full permissions, owners or timestamps. If an exercise depends on exact metadata, a fresh clone will not preserve it for you.

diff and patch

diff compares two files and describes how to turn the first into the second. The unified format (diff -u) is the one you will meet most:

$ diff -u shopping-old.txt shopping-new.txt
--- shopping-old.txt
+++ shopping-new.txt
@@ -1,3 +1,3 @@
 bread
-milk
+oat milk
 eggs

Lines starting with - are removed, lines with + are added, and unmarked lines are context. The @@ header gives the line ranges in each file. patch does the reverse: it reads such a description and applies it to a file. man patch explains how to choose the input and output files.

find: tests, operators, actions

find walks a directory tree and evaluates an expression for every entry. The expression is built from tests (-name, -type, -mtime, -size), operators (implicit "and", -o for "or", ! for "not", and escaped parentheses for grouping) and actions (-print, -exec, -delete).

$ find . -type f -name '*.log' -mtime +7

This lists regular files ending in .log that were modified more than seven days ago. Two details matter. Quote the pattern, or the shell may expand *.log before find ever sees it. And mind precedence: "and" binds tighter than "or", so an action placed after an -o may apply to only one side of it. Before adding any deleting action, run the same expression with -print and read the list.

Identifying files by content

Unix does not trust file extensions. The file command inspects a file's first bytes and compares them with a database of known signatures — "magic numbers" — to say what it contains:

$ file photo.jpg notes.txt
photo.jpg: JPEG image data
notes.txt: ASCII text

That database is extensible: you can describe new signatures (a byte offset, a type and a value to match) in a magic file of your own. The magic(5) manual page documents the format.

How to practise

Common mistakes

Where to go next

Handbook volume 1 in 42CodeLens, on Unix and shell foundations, is free as well.