Learn › Linux Foundations › Bash Shell Environment

Chapter 8, Part 2. Bash Shell Environment: alias, startup files, source, expansion and quoting

Final test: Chapter 8, Bash Shell Environment. Twenty-five objectives on a real Debian 12 server covering both parts: shell variables, env, printenv, export, unset, PATH, which and type, then alias, unalias, .bash_aliases, source, brace and tilde expansion and quoting. Fifty minutes, graded from what the programs record, from the files you create, and from the commands you run.

Chapter 8, Part 2. Bash Shell Environment

An alias works in one shell, then seems to disappear in the next. Find where this server loads aliases, make the definition available in the current shell, and check a new login. The same shell also expands braces, ~, variables, quotes and command output before a program receives its arguments.

Route: alias and startup files first, then expansions and quoting, then the chapter lab.

This is Part 2 of 2. Part 1 covered Sections 8.1 to 8.10, the values a shell holds and the way it finds a program. This part covers Sections 8.11 to 8.18: naming your own commands, the files that make a setting survive a login, the rewrites the shell performs on your line before anything runs, and command substitution, which puts the output of one command into the line of another. It ends in the chapter lab, which covers Sections 8.1 to 8.17.

What you already know: Part 1 showed that the shell rewrites your line before running it, replacing $NAME with a value. Every section here is another rewrite the shell does, or a way to control it. Chapter 5 read files with cat and head, and Chapter 6 copied them with cp; both tools appear again here.

Objectives

After this part you can:

Before you start a machine, each exercise shows a rehearsal terminal with recorded output. It checks the requested command but does not change Linux files. If your Part 1 practice machine is still running, continue on it; otherwise start a practice machine here. Commands run there, so an unintended command can still change it even if the lesson does not mark the exercise complete.

While the machine is running, files you created remain on it, but a new connection may start a fresh shell. Check which aliases and variables are present before using them; Section 8.14 teaches how to load installed aliases into the shell you are using. The final Test Room starts a separate prepared server and checks its objectives automatically. It covers Sections 8.1 to 8.17, while command substitution in Section 8.18 is lesson practice; completing a rehearsal exercise is not a Test Room result.

Pre-check 1 of 5: a name of your own

Five questions before the material. A wrong answer costs nothing: the explanation states the fact and names the section that teaches it.

Pre-check 2 of 5: making a setting last

Pre-check 3 of 5: reading a file into the shell

Pre-check 4 of 5: one word, three files

Pre-check 5 of 5: quotes

8.11 A short name for a command: alias

An alias is a word you define as a stand-in for a longer command. When the word is the first thing on your line, the shell replaces it with its definition, then runs the result. The definition goes in quotes so the shell stores it instead of running it now. An alias lives in the shell, not on disk, so this works wherever you stand. Define ll as ls -l:

prompt: admin@server1:~$ answer: alias ll='ls -l' ||| alias ll="ls -l" output: hint: Section 8.11. The word alias, the new name ll, an equals sign, then ls -l inside single quotes.

Silent. The alias exists in this shell from now until you remove it or the shell ends. Nothing was written to disk.

8.11 The definition the shell holds

alias with a name and no equals sign prints that definition back. Ask for ll:

prompt: admin@server1:~$ answer: alias ll output: alias ll='ls -l' hint: Section 8.11. The same word as Exercise 8-34, alias, then just the name ll.

The shell prints the definition in the form you could type back, with single quotes around the value whichever kind of quotes you used.

8.11 Using the alias

Anything you type after the alias is added to the end of the definition, so ll takes the same arguments ls does. List ~/logs through it; the home-rooted path works from any directory:

prompt: admin@server1:~$ answer: ll ~/logs ||| ll logs ||| ll /home/admin/logs ||| ll ~/logs/ output: total 1036 -rw-r--r-- 1 admin admin 791424 Jan 15 2026 access.log -rw-r--r-- 1 admin admin 49980 Jan 15 2026 auth.log -rw-r--r-- 1 admin admin 17000 Jan 15 2026 cron.log -rw-r--r-- 1 admin admin 192090 Jan 15 2026 error.log hint: Section 8.11. The short name you defined, ll, then the directory ~/logs.

The long listing from Section 2.4, reached by two letters. The shell replaced ll with ls -l and added your argument, so the command that ran was ls -l ~/logs. An alias is a text replacement of the first word, nothing more.

8.11 type sees an alias

Ask what kind of word ll is now that the alias exists:

prompt: admin@server1:~$ answer: type ll output: ll is aliased to `ls -l' hint: Section 8.10. The command that reports what kind of word a name is, then the name ll.

type reports an alias as an alias and shows what it stands for. which would find nothing, because an alias is not a file. This is why type is the tool to reach for when a command does something you did not expect.

8.12 Removing an alias: unalias

unalias takes the definition back. The name becomes an ordinary word again, and the shell looks for a program with that name as usual. Remove ll:

prompt: admin@server1:~$ answer: unalias ll output: hint: Section 8.12. The word unalias, then the name of the alias, ll.

Silent. From here the word ll means nothing to the shell, and typing it produces the same command not found message Part 1 met in Exercise 8-19. The step Errors you will meet quotes it.

8.13 Where the shell reads its settings: the startup files

Every setting so far lived in one shell and ended with it. Bash reads files of commands when it starts, and whatever those files contain happens by itself. Which file it reads depends on the kind of shell.

A login shell is the shell a session starts with, the kind Section 7.5 defined. It is what a connection over SSH gives you. Bash reads /etc/profile first, then the first one of your own that exists out of ~/.bash_profile, ~/.bash_login and ~/.profile. It stops at the first one it finds, so creating ~/.bash_profile on a machine that has ~/.profile means ~/.profile is never read again.

An interactive shell is one you type into. An interactive shell that is not a login shell, such as one you start by typing bash inside a session you already have, reads ~/.bashrc.

Debian joins the two. The ~/.profile it ships reads ~/.bashrc, so a login shell on this server reaches that file as well. The file begins by naming the case it was written for. Read the first five lines of ~/.bashrc; the path is home-rooted, so it reads the same from any directory:

prompt: admin@server1:~$ answer: head -5 ~/.bashrc ||| head -n 5 ~/.bashrc ||| head -5 /home/admin/.bashrc output:

~/.bashrc: executed by bash(1) for non-login shells.

see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)

for examples

If not running interactively, don't do anything

hint: Section 5.3. The command that prints the first lines of a file, its count option with 5, then the path ~/.bashrc.

The first line names the non-login case, and Debian's ~/.profile is what brings the file into a login shell as well. The fifth line is the other half of the rule: the file stops early when the shell is not interactive, so a script that runs bash gets none of it.

The rest is ordinary shell commands, run before your first prompt. Bash does not read ~/.bash_aliases by itself; a startup file must source it. Debian's ~/.bashrc has a line that reads that file when it exists. On this prepared server, ~/.profile reads ~/.bashrc and then sources ~/.bash_aliases, so the aliases are defined at each new login. A new interactive non-login Bash reads ~/.bashrc but not ~/.profile; do not assume it has the same aliases. Use source ~/.bash_aliases to load them into the shell you are already using.

8.13 The alias file to install

The tools directory holds a file of alias definitions, ready to be installed under that name. You are in your home directory. Read tools/aliases.sh:

prompt: admin@server1:~$ answer: cat tools/aliases.sh ||| cat ~/tools/aliases.sh output:

Aliases for server1. Copy this file to ~/.bash_aliases and every new login

defines them. Load them into the current shell with: source ~/.bash_aliases

alias ll='ls -l' alias la='ls -la' alias releases='ls ~/website/releases' alias backups='ls -lh ~/backups' hint: Section 5.1. The printing command, then the path tools/aliases.sh (or ~/tools/aliases.sh from anywhere).

Two comment lines, which the shell ignores, and four alias definitions in the form of Exercise 8-34. A file like this is the normal way an engineer carries a working environment from machine to machine.

8.13 The file is not there yet

You are in your home directory. Look for ~/.bash_aliases, the file the startup files read:

prompt: admin@server1:~$ answer: ls ~/.bash_aliases ||| ls /home/admin/.bash_aliases output: ls: cannot access '/home/admin/.bash_aliases': No such file or directory hint: Section 2.2. The listing command, then the path ~/.bash_aliases, written with the tilde so it names the same file from anywhere.

The message names the path the tilde stood for, which is one way to see what the shell did to your line before ls ran. Nothing reads ~/.bash_aliases yet, because there is nothing to read.

8.13 Nothing to read yet

Section 8.14 covers source, the builtin that reads a file into the shell you are typing in. Ask it to read ~/.bash_aliases now, before the file exists, and the message names the path:

prompt: admin@server1:~$ answer: source ~/.bash_aliases ||| . ~/.bash_aliases ||| source /home/admin/.bash_aliases output: bash: /home/admin/.bash_aliases: No such file or directory hint: Section 8.14. The word source, then the path ~/.bash_aliases.

The shell reports it, because source is part of the shell. It reads a file; it does not create one.

8.13 Installing the file

You are in your home directory. Copy tools/aliases.sh to ~/.bash_aliases:

prompt: admin@server1:~$ answer: cp tools/aliases.sh ~/.bash_aliases ||| cp ~/tools/aliases.sh ~/.bash_aliases ||| cp tools/aliases.sh /home/admin/.bash_aliases output: hint: Section 6.7. The copying command, the source tools/aliases.sh (or ~/tools/aliases.sh from anywhere), then the destination ~/.bash_aliases.

Silent, as cp is. The file now exists under the name the startup files look for, so every login from now on defines those four aliases. The shell you are in was started before the file existed, and knows nothing about it yet.

8.14 Reading a file into this shell: source

source is a builtin: it reads a file and runs every line of it in the shell you are typing in, rather than in a separate process. That is what makes its definitions stay.

Running bash ~/.bash_aliases instead is a different act. Bash starts a separate shell, that shell reads the lines and defines aliases only for itself, then exits and takes those definitions with it. This form asks Bash to read the file, so the file does not need execute permission. Nothing the separate shell defined reaches your current shell. Read ~/.bash_aliases into this shell:

prompt: admin@server1:~$ answer: source ~/.bash_aliases ||| . ~/.bash_aliases ||| source /home/admin/.bash_aliases output: hint: Section 8.14. The same command as Exercise 8-42, source and the path ~/.bash_aliases, now that the file is there.

Silent. Every line of the file ran in this shell, so the four aliases exist here now. A single dot is the same builtin under an older name, and . ~/.bash_aliases does exactly the same thing.

8.14 Every alias the shell holds

List every alias the shell holds. The word takes no arguments, so it answers the same wherever you stand:

prompt: admin@server1:~$ answer: alias output: alias backups='ls -lh ~/backups' alias la='ls -la' alias ll='ls -l' alias releases='ls ~/website/releases' hint: Section 8.11. The word alias on its own, with no name after it.

Four definitions in name order, including ll, which the file defined again after you removed it in Exercise 8-38.

8.14 Using one of them

Run one of them. releases lists ~/website/releases, so it works from any directory:

prompt: admin@server1:~$ answer: releases output: 2026-06-01 2026-07-15 2026-08-01 hint: Section 8.14. One word: releases, the name the file defined for the listing of ~/website/releases.

The three dated release directories from Chapter 2. The word releases is not a program anywhere on this machine; the shell replaced it with its definition and ran that.

8.14 Where it came from

Ask what kind of word releases is:

prompt: admin@server1:~$ answer: type releases output: releases is aliased to `ls ~/website/releases' hint: Section 8.10. The command that reports what kind of word a name is, then the name releases.

The definition the file installed. A name that behaves unexpectedly on a machine you did not set up is often an alias, and this is the command that shows it.

8.15 One word, many words: brace expansion

Brace expansion turns one word into several. The shell repeats the text around the braces once for each item inside them, separated by commas. It happens before the command runs, so the command receives ordinary separate arguments. Nothing is read from disk, so it works wherever you stand. echo shows what the shell built from report-{a,b,c}.txt:

prompt: admin@server1:~$ answer: echo report-{a,b,c}.txt output: report-a.txt report-b.txt report-c.txt hint: Section 8.15. The printing command, then one word made of the fixed start report-, the three letters a,b,c inside braces separated by commas, and the fixed ending .txt.

Three words from one. The text before the braces and the text after them is repeated for every item. No file was touched: this is the shell rewriting your line, and echo simply printed the result.

8.15 A range

Two dots between a first and a last value make a range instead of a list. Expand {1..5}:

prompt: admin@server1:~$ answer: echo {1..5} output: 1 2 3 4 5 hint: Section 8.15. The printing command, then 1, two dots and 5 inside braces.

Five words. Ranges work on letters too, and a range of dates or numbered directories is the usual reason to reach for one.

8.15 Three files in one command

Anything the shell builds this way can be handed to a real command. You are in your home directory, and tools/reports is empty. Create 2026-01.txt, 2026-02.txt and 2026-03.txt in it with one command:

prompt: admin@server1:~$ answer: touch tools/reports/2026-0{1,2,3}.txt ||| touch ~/tools/reports/2026-0{1,2,3}.txt ||| touch tools/reports/2026-{01,02,03}.txt ||| touch ~/tools/reports/2026-{01,02,03}.txt output: hint: Section 8.15. The file-creating command from Section 6.1, then tools/reports/2026-0{1,2,3}.txt (or ~/tools/reports/2026-0{1,2,3}.txt from anywhere).

Silent, as touch is. The shell handed touch three separate paths, so touch created three files without knowing a brace was involved.

8.15 The three files

You are in your home directory. List tools/reports:

prompt: admin@server1:~$ answer: ls tools/reports ||| ls ~/tools/reports ||| ls tools/reports/ output: 2026-01.txt 2026-02.txt 2026-03.txt hint: Section 2.2. The listing command, then the path tools/reports (or ~/tools/reports from anywhere).

Three files, one command. Typing them out one at a time would have produced exactly the same result and three chances to make a typing mistake.

8.15 Three directories with a range

A range builds directories the same way. You are in your home directory. Create q1, q2 and q3 inside tools/reports with one command:

prompt: admin@server1:~$ answer: mkdir tools/reports/q{1..3} ||| mkdir ~/tools/reports/q{1..3} output: hint: Section 6.2. The directory-making command, then tools/reports/q{1..3} (or ~/tools/reports/q{1..3} from anywhe

Practice Chapter 8, Part 2. Bash Shell Environment: alias, startup files, source, expansion and quoting in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.

More lessons in Bash Shell Environment