Hands-On: Unix Shell Basics

Introduction to HLRS Systems - Day 1 Afternoon

Work through the exercises below at your own pace. Each section lists the relevant commands as a quick reference. For details use man <command> or refer to the slides.
Use Ctrl+Shift+F to search for keywords on the lecture slides.

While you can use Ctrl+Shift+C / Ctrl+Shift+V to copy and paste, also type some of the commands by hand to retain the material better.

Before you begin

Tab ↑ ↓ Ctrl+R !!
  1. Tab completion. The shell can finish what you are typing. Type cd /et and press Tab. Then type ls /home/ and press Tab twice to list all options. It is typically faster than typing and catches typos before you make them.
  2. Command history. Press ↑ a few times to walk back through your previous commands. Now press Ctrl+R and type cd; the shell finds the most recent matching command. Press Enter to run it, or → to edit it first. Use history to see your full session, and !! to repeat the last command.

1   Navigation

pwd cd ls
On Linux, files and directories whose name begins with . are hidden; they don't show up in ls by default. These are called "dotfiles" and typically hold configuration (e.g., .bashrc, .ssh/).
  1. Print your current working directory. What is the path to your home directory?
  2. List the contents of your home directory, including hidden files (hint: use man ls to find the right flag).
  3. Navigate to /tmp, confirm your location, then return to your home directory.

    Running cd with no argument takes you home. cd ~ and cd $HOME work too.

  4. List the contents of /etc without leaving your home directory.

2   Files and Directories

mkdir cp mv rm cat less head tail
  1. Create an empty file with touch notes.txt. Open the file in nano and write a short note. Save with Ctrl+O, confirm the filename, then exit with Ctrl+X. Print the contents of notes.txt to the terminal. Then create a second file with a space in its name (my notes.txt) and remove both files.

    Filenames containing spaces must be quoted.

  2. Create the following directory structure inside your home directory:
    workshop/
    ├── data/
    └── results/
  3. Copy the file /etc/os-release into workshop/data/
  4. View the file with less (press q to quit). Then print only the first 5 lines using a single command.
  5. Rename the file to system-info.txt
  6. Create a second copy of system-info.txt in workshop/results/
  7. Delete the copy in workshop/results/
  8. Remove the entire workshop/ tree recursively in one command.

    Check man rm.     ⚠ There is no recycle bin on the command line.

  9. Wildcards: use a single ls command to list every file in /etc whose name ends in .conf.

    The shell expands * to match any sequence of characters before the command runs.

  10. Now list every file in /etc/ssh/ whose name starts with ssh.

3   Finding Files and Getting Help

man which find --help
Linux commands typically accept --help for a quick usage summary, while man <command> opens the full manual page (press q to quit).
  1. Open the manual page for cp. Which flag enables recursive copying? Close the manual when done.
  2. Find out where the python3 executable lives on this system.

    Note: Scripts executed by cron, batch systems, or other automation often run with a minimal PATH and may not find commands the way your interactive shell does. In such cases, using the full path (which which can give you) avoids surprises.

  3. Find all files in /etc whose name ends in .conf.

    You will see some "Permission denied" lines; that is normal. Append 2>/dev/null to the command to discard them.

4   Permissions

ls chmod groups id namei
  1. Run ls -l /etc/ssh/. How many regular files and how many directories are listed? Who owns them?

    The first character of each line is - for a regular file and d for a directory.

  2. Look at the permissions of /etc/passwd with ls -l. Can every user on the system read it? Can they modify it?
  3. Create a small script file:
    echo '#!/bin/bash' > hello.sh
    echo 'echo "Hello, Hunter!"' >> hello.sh
    Try to run it with ./hello.sh. What happens and why?
  4. Make the script executable for yourself only, then run it successfully.

    chmod u+x <file> adds execute permission for the user (owner).

  5. Which groups do you belong to? Try both groups and id. What extra information does id provide?
  6. Create a directory shared/ and a file shared/notes.txt with a line of text. You want these permissions:
    • you can read and write the file
    • group members can read but not write
    • others have no access at all
    Set them with two separate commands because the file and the directory are not the same:
    chmod 640 shared/notes.txt
    chmod 750 shared
    Verify with ls -l shared and ls -ld shared.

    Why 750 on the directory, not 640? The execute bit on a directory means "may enter it". Without it, even you could not reach notes.txt inside; so a directory needs x wherever you grant r. This is also why a single chmod -R 640 shared/ would lock you out. See the lecture slides on file permissions.

  7. Use namei -l <path> on the full path to shared/notes.txt to inspect permissions at every level.

5   Environment Variables

echo export
  1. Have a look at the PATH variable. How many directories does your PATH currently contain?

    Use: echo $PATH | tr ':' '\n' | wc -l

  2. Add a directory to your PATH so you can run a script from anywhere:
    mkdir ~/mybin
    echo 'echo Custom command works' > ~/mybin/hello
    chmod u+x ~/mybin/hello
    hello                                # command not found
    export PATH="$PATH:$HOME/mybin"
    hello                                # now prints: Custom command works
    The shell finds hello the second time because $HOME/mybin is now on your PATH, the list of directories it searches for commands. We use export because it is the form you will reuse in ~/.bashrc, and it makes sure programs you launch from this shell inherit the updated PATH too, not just the shell itself.
  3. Prepend $HOME/mybin to your PATH for this session and verify the change.

    Note: The operating system searches PATH from left to right and uses the first match. Prepending therefore lets your version take precedence over system commands; appending acts as a fallback. New shells will not remember previous exports; if you want to make your exports permanent, you have to write them into ~/.bashrc

  4. Compare the output of echo "$HOME" and echo '$HOME'. Why are they different?
  5. Set EMPTY="" , then run ls $EMPTY /tmp and ls "$EMPTY" /tmp. The first lists /tmp while the second gives an error. Explain the difference.

    Without quotes the shell removes empty arguments before ls sees them.

6   Pipelines & Redirection

| > >> 2>/dev/null
See the lecture slide for examples.
  1. Find all files in /etc and count how many there are with wc -l, discarding permission errors.

    Use find with the option -type f

  2. Write that file list to etc-contents.txt. Then append today's date to the end of the same file.

    Use > to write and >> to append. The date command prints the current date and time.

  3. Find the 5 longest lines in etc-contents.txt

    Hint: awk '{print length, $0}' adds the line length as a prefix. Combine with sort -n (numeric sort) and head or tail.

7   Searching with grep

grep -i -v -r -c -A / -B / -C
First, read what these options do with grep --help . See the lecture slide for examples.
  1. Search etc-contents.txt for lines containing conf, case-insensitively.
  2. Count how many lines in /etc/os-release do not contain an = sign.

    You'll need two flags: one to invert the match and one to count.

  3. Find lines containing NAME in /etc/os-release and show 2 lines of context after each match. Also try the other context options.

    -A <n> shows n lines after each match.

  4. Search recursively through /etc for any file containing the word hostname. Suppress permission errors.

    grep -r searches recursively. Append 2>/dev/null to discard errors.

8   Processes

ps jobs bg fg kill Ctrl+C Ctrl+Z &
  1. Start a long-running command in the foreground: sleep 120. Cancel it with Ctrl+C.
  2. Start sleep 120 again, but this time suspend it with Ctrl+Z. Use jobs to confirm it is stopped, then resume it in the background with bg. Verify with jobs again.
  3. Start a job in the background with sleep 300 &, bring it to the foreground with fg, then cancel it with Ctrl+C.

    fg is the counterpart to bg: bg sends a job to the background, fg pulls it back. With several jobs, use fg %<n> and the job number from jobs.

  4. Start a background job directly: sleep 300 &. Find its process ID with ps (or note the PID printed when you started it) and terminate it with kill <PID>.
  5. Run ps -fu $USER to see all your processes. What command started the shell you are typing into?

9   Archives

tar -czf tar -xzf tar -tzf du -sh
  1. Create a compressed archive backup.tar.gz of the /etc/ssh directory.

    You will see a few Permission denied lines for the private host keys, which only root can read. That is expected, and the archive still contains everything you are allowed to read.

  2. List the contents of the archive without extracting it.
  3. Extract the archive into a new directory ssh-backup/ in your home directory.

    mkdir ssh-backup first, then extract with tar -xzf <archive> -C ssh-backup.

  4. How large is the archive compared to the unpacked directory?

10   Putting It Together

  1. Largest files: Find the 5 largest files in /usr/bin by size.

    Hint: ls -lS sorts by size and adding -h makes it human-readable.

  2. Line count comparison: Find which of these system files has the most lines: /etc/passwd, /etc/group, /etc/services.

    wc -l accepts multiple files at once and prints one line per file (plus a total row at the end). Strip the total with grep -v total, then pipe through sort -nr to put the longest file first.

  3. Free exploration: Use any combination of tools to answer: how many distinct file extensions exist in /etc?

    Hint: grep -o '\.[^./]*$' extracts the last extension from each filename. Combine with find, sort, and uniq (or sort -u) to count distinct extensions.

Errors you may see


When you are finished, feel free to clean up any files created during the exercises.