Home Blog Certs Knowledge Base About

LPIC-1 105.1 โ€” Aliases, Functions, and Special Variables (Part 3)

Exam weight: 4 โ€” LPIC-1 v5, Exam 102 | Part 3 of 105.1

Aliases โ€” Advanced Usage

Quotes and Variables Inside an Alias

Commands with spaces, options, or chains must be quoted inside an alias. Otherwise Bash treats the first space as the end of the definition.

$ alias ll='ls -al'
$ alias greet='echo Hello world!'

A variable value can be embedded in an alias:

$ reptile=uromastyx
$ alias greet='echo Hello $reptile!'
$ greet
Hello uromastyx!

A variable can also be set inside the alias itself, separated by a semicolon:

$ alias greet='reptile=tortoise; echo Hello $reptile!'
$ greet
Hello tortoise!

Dynamic vs Static Expansion

The type of quotes determines when a variable is expanded.

Single quotes โ€” defer expansion until the alias is invoked:

$ alias where?='echo $PWD'
$ where?
/home/user2
$ cd Music
$ where?
/home/user2/Music          # expands to current directory each time

Double quotes โ€” expand the variable immediately when the alias is created, fixing the value:

$ alias where?="echo $PWD"
$ where?
/home/user2
$ cd Music
$ where?
/home/user2                # still the old directory

Simple rule: single quotes = dynamic, double quotes = static.

Alias Inside an Alias

An alias can call another alias by name:

$ alias where?='echo $PWD'
$ alias my_home=where?
$ my_home
/home/user2

Command Chain with Semicolons

An alias can run multiple commands separated by semicolons:

$ alias git_info='which git; git --version'
$ git_info
/usr/bin/git
git version 2.7.4

Bash Functions โ€” Advanced Usage

Single-line Function Definition

A function can be written on one line. Semicolons separate commands, and a semicolon is required after the last command before the closing brace:

$ greet() { greeting="Hello world!"; echo $greeting; }
$ greet
Hello world!

When typing a function interactively line by line, Bash shows the > continuation prompt (PS2) until the block is closed:

$ greet() {
> greeting="Hello world!"
> echo $greeting
> }

Variables Inside Functions

A function works with both local shell variables and environment variables. Given a file funed with:

editors() {
    editor=emacs
    echo "My editor is: $editor. $editor is a fun text editor."
}

Source and call it:

$ . funed
$ editors
My editor is: emacs. emacs is a fun text editor.

The variable editor set inside the function remains in the current shell after the call:

$ echo $editor
emacs

Environment variables like $USER can also be used inside functions:

editors() {
    editor=emacs
    echo "The text editor of $USER is: $editor."
}
editors

If the function call is the last line of the file, sourcing the file immediately invokes it.

Positional Parameters in Functions

Parameters are passed either from the file itself or from the command line.

From the file:

editors() {
    editor=emacs
    echo "The text editor of $USER is: $editor."
    echo "Bash is not a $1 shell."
}
editors tortoise

From the command line (remove the invocation from the file, source just the definition, then call):

$ . funed
$ editors tortoise
The text editor of user2 is: emacs.
Bash is not a tortoise shell.

Aliases and Positional Parameters

Technically you can pass arguments to an alias, but they always go to the end of the expanded line, regardless of where $1 is placed:

$ alias great_editor='echo $1 is a great text editor'
$ great_editor emacs
is a great text editor emacs

For proper positional parameter handling, use functions, not aliases.


Special Built-in Bash Variables

These variables are read-only โ€” you can read them but not assign to them directly.

$? โ€” Last Exit Code

Stores the exit code of the last command. 0 means success:

$ ps aux | grep bash
user2  420  ... -bash
$ echo $?
0

Non-zero means an error:

$ ps aux | rep bash
-bash: rep: command not found
$ echo $?
127

$$ โ€” Shell PID

Current shell’s process ID:

$ echo $$
420

$! โ€” Background Job PID

PID of the last process started in the background with &:

$ ps aux | grep bash &
[1] 663
$ echo $!
663

Positional Parameters $0..$9

$0 โ€” script or shell name. $1โ€“$9 โ€” arguments passed to a function or script:

$ special_vars() {
> echo $0
> echo $1
> echo $2
> echo $3
> }
$ special_vars debian ubuntu zorin
-bash
debian
ubuntu
zorin

Other Special Variables

VariableMeaning
$#Number of arguments passed
$@ / $*All arguments
$_Last argument of the previous command (or script name at startup)

Full list: man bash, section SPECIAL PARAMETERS.


Functions in Scripts

Functions appear most often inside Bash scripts. Converting the funed file to a script funed.sh takes two additions:

#!/bin/bash
editors() {
    editor=emacs
    echo "The text editor of $USER is: $editor."
    echo "Bash is not a $1 shell."
}
editors tortoise

What changed:

  • The shebang #!/bin/bash on line 1 tells the kernel which interpreter to use.
  • The last line calls the function. Without it, the script would only define it and exit.

Make it executable and run:

$ chmod +x funed.sh
$ ./funed.sh
The text editor of user2 is: emacs.
Bash is not a tortoise shell.

Function Inside an Alias

A function definition can be embedded in an alias, together with its invocation and self-cleanup:

$ alias great_editor='gr8_ed() { echo $1 is a great text editor; unset -f gr8_ed; }; gr8_ed'

How it works:

  1. gr8_ed() { ... } defines the function.
  2. unset -f gr8_ed inside the function removes it from the session after it runs.
  3. ; gr8_ed at the end calls the function.

Test:

$ great_editor emacs
emacs is a great text editor

unset flags:

FlagEffect
unset -v NAMERemove a variable
unset -f NAMERemove a function
unset NAMERemove variable first; if none, remove function

Function Inside a Function

One function can call another. Example: add to ~/.bashrc so that on login the user gets a greeting and a video folder check.

check_vids โ€” lists mkv files and warns the user:

check_vids() {
    ls -1 ~/Video/*.mkv > /dev/null 2>&1
    if [ "$?" = "0" ]; then
        echo -e "Remember, you must not keep more than 5 video files in your Video folder.\nThanks."
    else
        echo -e "You do not have any videos in the Video folder. You can keep up to 5.\nThanks."
    fi
}

Step by step:

  • > /dev/null 2>&1 redirects both stdout and stderr to /dev/null (the bit-bucket).
  • [ "$?" = "0" ] checks whether the previous command succeeded.

editors โ€” greets the user and calls check_vids:

editors() {
    editor=emacs
    echo "Hi, $USER!"
    echo "$editor is more than a text editor!"
    check_vids
}

editors

The last line of the file calls editors, which in turn calls check_vids.

Test by switching to the user:

# su - user2
Hi, user2!
emacs is more than a text editor!
Remember, you must not keep more than 5 video files in your Video folder.
Thanks.

Quick Reference

# Special variables
echo $?      # exit code of last command (0 = success)
echo $$      # PID of current shell
echo $!      # PID of last background process
echo $0      # script/shell name
echo $1      # first positional argument
echo $#      # number of arguments
echo $@      # all arguments

# unset
unset -v NAME   # remove variable
unset -f NAME   # remove function

# Alias with command chain
alias git_info='which git; git --version'

# Single-line function (semicolon required after last command)
greet() { greeting="Hello world!"; echo $greeting; }

# Shebang
#!/bin/bash

# Make script executable and run
chmod +x script.sh
./script.sh

# readonly function
readonly -f my_fun     # make function read-only
readonly -f            # list all read-only functions

Exam Questions

  1. Difference between single and double quotes in alias definition? โ†’ Single quotes defer variable expansion until the alias is invoked. Double quotes expand the value immediately when the alias is created.
  2. What does $? hold right after a successful command? โ†’ 0.
  3. Difference between $$ and $!? โ†’ $$ is the PID of the current shell. $! is the PID of the last background process.
  4. Why do positional parameters not work correctly in aliases? โ†’ Arguments always go to the end of the expanded alias string, regardless of where $1 appears. Use functions for positional parameters.
  5. Which two flags of unset specify the type of entity to remove? โ†’ -v for variables, -f for functions.
  6. What must the first line of a Bash script contain for it to run with the right interpreter? โ†’ A shebang: #!/bin/bash.
  7. How to prevent a function defined inside an alias from persisting in the session? โ†’ Add unset -f funcname as the last command inside the function, and call the function at the end of the alias definition.
  8. What does readonly -f do? โ†’ Makes a function read-only; it cannot be redefined or removed with unset -f.
  9. What does $# hold? โ†’ The number of arguments passed to the function or script.
  10. What does $@ expand to? โ†’ All positional arguments as a list.
  11. What is $_? โ†’ The last argument of the previous command (or the script name at startup).

Exercises

Exercise 1 โ€” Aliases vs functions capabilities

Fill in Yes or No.

CapabilityAliasesFunctions
Can use local variables??
Can use environment variables??
Can be escaped with \??
Support recursion??
Work well with positional parameters??
Answer
CapabilityAliasesFunctions
Can use local variablesYesYes
Can use environment variablesYesYes
Can be escaped with \YesNo
Support recursionYesYes
Work well with positional parametersNoYes

Escaping with \ applies to aliases because they can shadow built-in commands at parse time. Functions don’t have that name-collision issue.

Positional parameters in aliases always append to the end of the expanded string โ€” they don’t substitute into $1, $2. Use functions when you need argument handling.


Exercise 2 โ€” List all aliases

Answer
alias

Exercise 3 โ€” Alias logg for ogg files

Create alias logg that lists all ogg files in ~/Music, one per line.

Answer
alias logg='ls -1 ~/Music/*ogg'

The -1 option (digit one) forces one filename per line. The glob *ogg matches any name ending in ogg.


Exercise 4 โ€” Call the alias

Answer
logg

Exercise 5 โ€” Extend logg to greet the user

Modify logg to first print the current username and a colon, then the list.

Answer
alias logg='echo $USER:; ls -1 ~/Music/*ogg'

The two commands are joined by a semicolon. Single quotes defer $USER expansion until invocation, so it picks up the current user’s name.


Exercise 6 โ€” Call the updated alias

Answer
logg

Exercise 7 โ€” Verify logg is in the alias list

Answer
alias

Exercise 8 โ€” Remove the alias

Answer
unalias logg

Exercise 9 โ€” Match alias names to commands

Write correct definitions for these aliases.

NameCommand
bbash
bash_infoprint bash path and version
kernel_infoprint kernel release
greetprint Hi, $USER
computerset pc=slimbook, print My computer is a $pc
Answer
alias b=bash
alias bash_info='which bash; echo "$BASH_VERSION"'
alias kernel_info='uname -r'
alias greet='echo Hi, $USER'
alias computer='pc=slimbook; echo My computer is a $pc'

Single quotes are used so that $USER, $BASH_VERSION, and $pc are expanded at invocation time, not at definition time. For b=bash, no quotes are needed because the value has no spaces.


Exercise 10 โ€” Function my_fun in /etc/bash.bashrc

As root, write function my_fun that greets the user and prints their PATH. It should run on every login.

Answer

Variant A (parentheses syntax):

my_fun() {
    echo Hello, $USER!
    echo Your path is: $PATH
}
my_fun

Variant B (function keyword syntax):

function my_fun {
    echo Hello, $USER!
    echo Your path is: $PATH
}
my_fun

The function call on the last line is required; without it the function is only defined, not executed.

/etc/bash.bashrc is sourced for interactive non-login shells. For login sessions, either source it from /etc/profile, or add the code to both files.


Exercise 11 โ€” Switch to user2 to test

Answer
su - user2

The dash starts a login shell that runs the full set of startup files.


Exercise 12 โ€” Same function as a one-liner

Answer

Variant A:

my_fun() { echo "Hello, $USER!"; echo "Your path is: $PATH"; }

Variant B:

function my_fun { echo "Hello, $USER!"; echo "Your path is: $PATH"; }

A semicolon is required after the last command, before the closing brace.


Exercise 13 โ€” Call the function

Answer
my_fun

Exercise 14 โ€” Remove the function

Answer
unset -f my_fun

The -f flag tells unset to remove a function. Without it, unset first tries to remove a variable of the same name.


Exercise 15 โ€” Predict the output of special_vars2

Function:

special_vars2() {
    echo $#
    echo $_
    echo $1
    echo $4
    echo $6
    echo $7
    echo $_
    echo $@
    echo $?
}

Call: special_vars2 crying cockles and mussels alive alive oh

Answer
LineOutput
echo $#7
echo $_7
echo $1crying
echo $4mussels
echo $6alive
echo $7oh
echo $_oh
echo $@crying cockles and mussels alive alive oh
echo $?0

Seven arguments were passed: crying cockles and mussels alive alive oh. So $#=7, $1=crying, $4=mussels, $6=alive, $7=oh.

$_ holds the last argument of the previous command. After echo $# (which printed 7), $_ becomes 7. After echo $7 (which printed oh), $_ becomes oh.

$@ expands to all arguments. $? is 0 because echo $@ succeeded.


Exercise 16 โ€” Parameterized check_music function

Write check_music, a startup-script function based on check_vids. Make it accept positional parameters for: folder name, file extension, maximum count, file type label.

Answer
check_music() {
    ls -1 ~/$1/*.$2 > /dev/null 2>&1
    if [ "$?" = "0" ]; then
        echo -e "Remember, you must not keep more than $3 $4 files in your $1 folder.\nThanks."
    else
        echo -e "You do not have any $4 files in the $1 folder. You can keep up to $3.\nThanks."
    fi
}
check_music Music ogg 7 music

Parameter mapping: $1=Music (folder), $2=ogg (extension), $3=7 (limit), $4=music (label in the message).

ls ... > /dev/null 2>&1 discards both stdout and stderr. The exit code via $? is checked against 0 to decide which message to print.


Exercise 17 โ€” Read-only functions

How do you make a function read-only? How do you list all read-only functions?

Answer
readonly -f my_fun    # make read-only
readonly -f           # list all read-only functions

A read-only function cannot be redefined or removed with unset -f. To undo it you must start a new shell session.


Exercise 18 โ€” fyi function with system summary

Write a fyi function for a startup script that prints: username, home directory, hostname, OS type, PATH, mail directory, mail check interval, shell nesting level, and changes PS1 to <user>@<host-date>.

Answer
fyi() {
    echo -e "For your Information:\n
    Username: $USER
    Home directory: $HOME
    Host: $HOSTNAME
    Operating System: $OSTYPE
    Path for executable files: $PATH
    Your mail directory is $MAIL and is searched every $MAILCHECK seconds.
    The current level of your shell is: $SHLVL"
    PS1="\u@\h-\d "
}
fyi

Environment variables used: $USER, $HOME, $HOSTNAME, $OSTYPE, $PATH, $MAIL, $MAILCHECK, $SHLVL.

In the PS1 string: \u = username, \h = hostname (up to first dot), \d = date. Full list of prompt escape sequences: man bash, section PROMPTING.

The -e flag for echo enables interpretation of escape sequences such as \n (newline).


LPIC-1 Study Notes | Topic 105: Shells and Shell Scripting