Signal9Signal9 — home
online
all lessons

RHCSA Essential Tools: Shell, Files, Redirection, SSH, Archives

Beginner35 min6 steps
What you'll learn
  • Redirect a command's output and errors to files, and chain commands with pipes
  • Tell a hard link from a symbolic link, and predict which one breaks when the target moves
  • Set up passwordless SSH login with ssh-keygen and ssh-copy-id
  • Create, list, and extract tar archives without second-guessing the flags
  1. Why these four tools sit on the exam

    Frame redirection, links, SSH keys, and tar as the daily plumbing every sysadmin reaches for.

    The RHCSA doesn't test trivia — it tests the moves you'd make on a real server. Four of those moves show up constantly:

    • Redirection decides where a command's output goes — to your screen, to a file, or into another command.
    • Links let one file live in two places at once, which is how packages, configs, and /etc/alternatives actually work.
    • SSH keys are how you log into a machine without typing a password every time — and how automation logs in at all.
    • tar is how you bundle a directory into one file to move, back up, or ship it.

    Think of these as a plumber's core fittings. You don't admire them; you use them a hundred times a day without thinking. This lesson makes them reflex.

  2. Redirection: steering output and errors

    Send stdout and stderr where you want them, and stitch commands together with pipes.

    Every command has three streams. stdout (file descriptor 1) is its normal output. stderr (file descriptor 2) is its error messages. stdin (0) is its input. By default stdout and stderr both land on your terminal, which is why errors and results look mixed together.

    Redirection lets you point each stream somewhere else. Picture the command as a tap with two spouts — one for clean water (stdout), one for grit (stderr). Redirection is the plumbing that decides which bucket each spout fills.

    echo "web01" > hosts.txt
    >
    Redirect stdout to a file, OVERWRITING its contents (truncates first).
    > sends stdout into hosts.txt, replacing whatever was there. Success is silent — the text went to the file instead of the screen, which is why you see no output. The file now contains exactly one line: web01.
    echo "db01" >> hosts.txt
    >>
    Redirect stdout to a file, APPENDING to the end (keeps existing contents).
    >> appends instead of overwriting. After this, hosts.txt holds two lines: web01 then db01. The single most common redirection mistake is reaching for > when you meant >> and wiping out a file you wanted to add to.

    Errors travel on a separate stream, so > alone never captures them. To redirect errors you name the stream explicitly with 2>, and to fold errors into the same place as output you use 2>&1 ("send stream 2 to wherever stream 1 is going").

    ls /etc /nope > out.txt 2> err.txt
    2>
    Redirect stderr (fd 2) to a file, separate from normal output.
    Two destinations at once. The successful listing of /etc (stdout) goes to out.txt; the No such file or directory complaint about /nope (stderr) goes to err.txt. Splitting the streams lets you keep good results and error noise in separate files.
    ls /etc /nope > all.txt 2>&1
    2>&1
    Redirect stderr to the current destination of stdout (merge the two streams).
    2>&1 means "make stderr go to the same place stdout is currently going." Because > all.txt already pointed stdout at the file, both streams now land in all.txt together. Order matters: the > all.txt must come before 2>&1, or stderr gets redirected to the terminal's old stdout instead.

    A pipe (|) is redirection between two commands: it wires the stdout of the left command into the stdin of the right one, with no temp file in between. This is the heart of the Unix philosophy — small tools chained together.

    cat /etc/passwd | grep -c bash
    3
    |
    Pipe: connect the stdout of the left command to the stdin of the right command.
    -c
    grep flag: print the COUNT of matching lines instead of the lines themselves.
    cat streams the file to stdout; the | feeds that stream straight into grep, which counts the lines containing bash. No intermediate file is created — the data flows through memory. Here, 3 accounts use a bash login shell.

    Check yourself

    You want to keep adding new server names to an existing inventory file without erasing what's already there. Which redirection operator do you use?

    Check yourself

    Which operator merges a command's error messages into the same place its normal output is already being sent?

  3. Hard links vs. symbolic links

    Predict, from how each link is built, which one survives the target moving.

    On Linux a filename is just a label pointing at an inode — the actual on-disk object holding your data and metadata. Two kinds of link give a file a second name, and they differ in what they point at.

    • A hard link (ln target newname) is a second filename pointing at the same inode. There is no "original" and "copy" — both names are equal owners of one piece of data.
    • A symbolic link (ln -s target newname) is a tiny separate file whose contents are just the path string to the target. It points at a name, not at the data.

    Analogy: a hard link is two keys cut for the same lock — either key opens the identical door. A symlink is a sticky note that says "the office is down the hall, room 204." If room 204's nameplate moves, the sticky note now points at nothing.

    echo "config v1" > app.conf; ln app.conf app.hardlink; ls -li app.conf app.hardlink
    1572301 -rw-r--r-- 2 root root 10 Jun 23 14:02 app.conf
    1572301 -rw-r--r-- 2 root root 10 Jun 23 14:02 app.hardlink
    -i
    ls flag: show each file's inode number — the way to PROVE two names share one inode.
    -l
    ls flag: long format, which also exposes the link count after the permission bits.
    The first column is the inode number, and both files show the same one (1572301) — proof they are the very same data, not a copy. The 2 in the link-count column (after the permissions) means two names now point at this inode. Edit one and the other changes, because there is only one file underneath.
    ln -s app.conf app.symlink; ls -li app.symlink
    1572988 lrwxrwxrwx 1 root root 8 Jun 23 14:05 app.symlink -> app.conf
    -s
    ln flag: make a SYMBOLIC link (a path pointer) instead of a hard link.
    A symlink has its own inode (1572988, different from the target's 1572301), the type bit is l for link, and ls shows the -> app.conf arrow spelling out the path it stores. It doesn't hold the data — it holds the route to the data.

    Example — not runnable on your lab box

    mv app.conf app.conf.bak; cat app.symlink
    cat: app.symlink: No such file or directory
    This is the key difference made visible. The symlink still stores the text app.conf, but no file by that name exists anymore — it was renamed. The link is now dangling and resolves to nothing. A hard link would have been unaffected by this rename, because it points at the inode, not the name.

    Check yourself

    What command and option would you use to prove that two filenames refer to the very same inode?

    Check yourself

    You move a file to a new path. Which link type now points at nothing — the hard link or the symbolic link?

  4. Passwordless login with SSH keys

    Generate a key pair and install the public half so a login needs no password.

    Typing a password into every SSH session is slow, and it's a secret that can be guessed or phished. Key-based authentication replaces it with a matched pair of files:

    • a private key (~/.ssh/id_ed25519) that never leaves your machine, and
    • a public key (~/.ssh/id_ed25519.pub) that you freely hand to any server you want to log into.

    The server stores your public key; when you connect, the two halves prove to each other that they match, without the private key ever crossing the wire. Think of the public key as a padlock you mail to a server, and the private key as the only key that opens it. You can mail copies of the padlock to a hundred servers; only you hold the key.

    ssh-keygen -t ed25519 -C "webadmin@workstation"
    Generating public/private ed25519 key pair.
    Enter file in which to save the key (/home/webadmin/.ssh/id_ed25519):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/webadmin/.ssh/id_ed25519
    Your public key has been saved in /home/webadmin/.ssh/id_ed25519.pub
    The key fingerprint is:
    SHA256:Hq2v...8kdP webadmin@workstation
    -t ed25519
    Choose the key TYPE. ed25519 is the current best-practice algorithm (use -t rsa -b 4096 only for legacy servers).
    -C
    Attach a COMMENT (here an email/label) so you can tell whose key it is later in authorized_keys.
    This writes two files: the private id_ed25519 (guard it) and the public id_ed25519.pub (shareable). The passphrase, if you set one, encrypts the private key on disk — a second layer if the file is ever stolen. ed25519 is the modern default: short keys, strong security.
    ssh-copy-id webadmin@198.51.100.20
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'webadmin@198.51.100.20'"
    and check to make sure that only the key(s) you wanted were added.
    -i
    Optionally name WHICH public key to copy, e.g. -i ~/.ssh/id_ed25519.pub, if you have several.
    ssh-copy-id appends your public key to the remote account's ~/.ssh/authorized_keys file. It asks for the password this one time to get in and install the key; from now on the key does the proving. It also sets the correct restrictive permissions, which is the step people forget when they do it by hand.
    ssh webadmin@198.51.100.20
    Last login: Tue Jun 23 14:11:07 2026 from 192.0.2.5
    [webadmin@web01 ~]$
    No password prompt — you're straight to a shell. The server found your public key in authorized_keys, challenged your client to prove it held the matching private key, your client answered silently, and you're in. That clean, promptless login is exactly the end state a graded task checks for.

    Check yourself

    Which of your two key files gets installed on the remote server's authorized_keys?

  5. Bundling directories with tar

    Create, list, and extract a tar archive and stop guessing at the letters.

    tar (tape archive) rolls a whole directory tree into a single file so you can move, back up, or ship it. Its flags look cryptic until you learn the one verb that picks the mode and the supporting letters around it:

    • c = create an archive
    • x = extract from one
    • t = list (table of contents) what's inside
    • z = run it through gzip compression
    • v = verbose (print each file as it's processed)
    • f = the file that follows is the archive name

    Read tar czf as "create, gzip, file:" — verb first, then options, then the filename. The mnemonic that saves you on the exam: create, extract, list, and always an f.

    tar czf backup.tar.gz /etc/ssh
    tar: Removing leading `/' from member names
    c
    CREATE a new archive.
    z
    Compress (or decompress) the stream with gzip — the .gz in the name.
    f
    The next argument is the archive FILENAME. Forgetting f is the classic tar mistake.
    This creates (c) a gzip-compressed (z) archive into the file (f) backup.tar.gz, packing the whole /etc/ssh directory. The one line of output is a normal note: tar strips the leading / so the archive holds relative paths and won't clobber your real /etc/ssh on extraction.
    tar tzf backup.tar.gz
    etc/ssh/
    etc/ssh/ssh_config
    etc/ssh/sshd_config
    etc/ssh/moduli
    etc/ssh/ssh_host_ed25519_key.pub
    t
    List the table of contents (the files inside) WITHOUT extracting.
    t lists the contents without unpacking anything — a safe way to inspect an archive before you trust it. Note the paths are relative (etc/ssh/..., no leading slash), the result of that Removing leading / step. Always list before you extract, so you know what's about to land and where.

    Example — not runnable on your lab box

    tar xzf backup.tar.gz -C /tmp/restore
    x
    EXTRACT the archive's contents.
    -C
    Change to this directory before extracting — control WHERE files land.
    x extracts the archive. Silent success again. -C /tmp/restore tells tar to unpack there rather than the current directory — so the relative etc/ssh/... paths recreate under /tmp/restore/etc/ssh/. Extracting into a chosen directory keeps you from scattering files across your cwd by accident.

    Check yourself

    Which single tar letter creates a new archive, and which one extracts an existing one?

  6. Try it in your live terminal

    Do all four moves yourself on the real sandbox to your right.

    You have a real shell. Run these in order — they're safe (everything stays in /tmp/sig9-lab) and together they exercise redirection, links, and tar end to end. Watch each result and connect it back to the concept.

    mkdir -p /tmp/sig9-lab && cd /tmp/sig9-lab && echo "web01" > hosts.txt && echo "db01" >> hosts.txt && cat hosts.txt
    Redirection in action: > creates the file with one line, >> appends a second. cat should show both web01 and db01 — proof that append kept the first line.
    ln hosts.txt hosts.hard && ln -s hosts.txt hosts.sym && ls -li hosts.txt hosts.hard hosts.sym
    Compare inode numbers: hosts.txt and hosts.hard share one (hard link); hosts.sym has its own and shows the -> arrow (symlink).

    Example — not runnable on your lab box

    mv hosts.txt hosts.renamed && cat hosts.hard; cat hosts.sym
    After moving the original: the hard link still prints both lines (it points at the inode); the symlink now errors out (it pointed at the old name). This is the difference made real.

    Example — not runnable on your lab box

    tar czf inventory.tar.gz hosts.hard hosts.renamed && tar tzf inventory.tar.gz
    Create a gzip archive of your files, then list it without extracting. You should see both filenames inside — the create/list halves of the tar workflow, every flag including f present.
Recap
  • Redirection routes streams: > overwrites stdout, >> appends, 2> peels off errors, 2>&1 merges them, and | pipes one command into the next.
  • A hard link is a second name on the same inode (prove it with ls -i); a symlink is a path pointer that dangles if the target moves.
  • SSH key login means the public key goes into the server's authorized_keys; the private key never leaves your machine.
  • tar's mode letter leads — create, extract, list — and every tar command carries an f for the filename.
Command → effect
CommandWhat it doesWatch for
cmd > fileSend stdout to file, overwritingTruncates first — wipes existing contents
cmd >> fileAppend stdout to fileUse this to add lines, not >
cmd 2> file / 2>&1Capture errors / merge errors into stdoutPut 2>&1 after the stdout redirect
ln a bHard link: second name, same inodeNot a copy — edits show in both; same-filesystem only
ln -s a bSymlink: a pathname pointerDangles if target is moved or renamed
ssh-keygen -t ed25519Make a key pairKeep the private key; share only the .pub
ssh-copy-id user@hostInstall public key on a serverAppends to remote authorized_keys
tar czf a.tar.gz dirCreate a gzip archiveAlways include f
tar tzf a.tar.gzList archive contentsInspect before extracting
tar xzf a.tar.gz -C dirExtract into a chosen directory-C controls where files land