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):
- Names are exact. A file called
Notesis notnotes, and a trailing space in a name is part of the name. - Nothing extra. Leftover test files in a turn-in directory can fail it.
- Metadata is part of the answer. Permissions, sizes and dates are checked, not just contents.
- Order matters. Exercises tend to be graded in sequence, so a mistake early on can stop later work from counting.
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:
| Digit | Bits | Meaning |
|---|---|---|
7 | rwx | read, write and execute |
6 | rw- | read and write |
5 | r-x | read and execute |
4 | r-- | 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
-— the type:-regular file,ddirectory,lsymbolic link.rw-r-----— the permissions, user / group / others.1— the link count: how many names point at this file.aliceandstaff— the owner and the group.1204— the size in bytes.Mar 3 10:15— the modification time. For files older than about six months,lsshows the year instead of the time.report.txt— the name.
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.
Hard links and symbolic links
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
- Work in a scratch directory where mistakes cost nothing, then rebuild the real answer cleanly.
- Verify with a second tool. After setting permissions,
read them back with
ls -l; after writing a file, check it withcat -eandwc -c. - Read the manual page before searching the web. The
answer to "which option does that?" is almost always in
man, and exams will not give you a browser. - Start from a clean state and redo an exercise from memory. If you cannot, you learned the command, not the idea.
- Check on the system you are graded on. Options and output formats can differ between Linux and macOS.
Common mistakes
- A missing or extra newline at the end of a file.
- Permissions set on the wrong file, or lost after copying the file around.
- Test files, editor backups or hidden files left in a turn-in directory.
- An unquoted pattern expanded by the shell instead of by the command.
- Trusting that a command "looks right" instead of reading its actual output.
Where to go next
Handbook volume 1 in 42CodeLens, on Unix and shell foundations, is free as well.