Variables in Shell Scripting
- Variables are placeholders to store data (strings, numbers, paths, etc).
- They don’t require explicit declaration type (untyped).
- Stored as strings by default in bash/sh.
Creating Variables
| |
Note: ⚠️ No spaces around =.
Using Variables
| |
$var→ expands value(referencing the value of a variable)${var}→ safer form, avoids ambiguity, and useful for appending
| |
Types of Variables
User-defined variables (you create)
city="Multan"Environment variables (system-wide, inherited by child processes)
| |
Best Practices
- Use uppercase for environment vars (
PATH,HOME) - Use lowercase for local script vars (
count,name) - Quote variables to avoid word-splitting
echo "$path"
Read-only Variables
| |
Also you can use the declare -r variable_name to make constant.
| |
Delete variable and List Variable
List All Variables
| |
It will display all variables
Delete a Variable
| |
Quoting
Single Quotes (' ')
- Everything inside single quotes is taken literally.
- Variables, command substitution, and escape sequences do not work.
- You cannot put a literal single quote
'inside single quotes (unless you end and restart quoting or escape cleverly).
Example:
| |
Output:
| |
(Here $USER is not expanded.)
Double Quotes (" ")
- Double quotes are partially literal.
- Special characters like
$,`, and\are still interpreted. - Variables and command substitution are expanded.
- Good choice when you want text with spaces but still allow variable substitution.
Example:
| |
Output (suppose user is ahmad):
| |
Another example with command substitution:
| |
Output:
| |
Escape Character (\)
- Backslash escapes the next character, meaning it loses its special meaning.
- Useful to print characters like
$,",',\, or space.
Example:
| |
Rule of Thumb
- Use single quotes when you want exact literal text.
- Use double quotes when you want variables and commands to expand.
- Use backslash for one-off escapes.
Environment and Shell Local Variables
Local (Shell) Variables
- Exist only in the current shell session (not inherited by child processes).
- They disappear when the shell is closed.
- Default when you create variables with
VAR=valuewithout exporting.
Example:
| |
✔ Local to the shell, not shared with subshells or programs.
- User configuration file: ~/.bashrc ~/.zshrc
- System-wide configuration file: /etc/bash.bashrc and /etc/profile
Environment Variables
- Variables that are exported to child processes.
- Used by system programs, shells, and user applications.
- Example:
PATH,HOME,USER,LANG.
Create/Export an Environment Variable
| |
Save them permanently add them to your .bashrc or .zshrc etc file.
Commands for Working with Variables
set
- Lists all variables (local + environment + shell functions).
| |
printenv or env
- Shows only environment variables.
| |
export
- Marks a variable as environment.
| |
Special Variables (Shell Built-ins)
$0→ Script name$1,$2→ Positional parameters (arguments to script)$#→ Number of arguments$$→ PID of current shell$?→ Exit status of last command$USER,$HOME,$PATH→ Common environment variables
Key Differences
| Feature | Local Variable | Environment Variable |
|---|---|---|
| Scope | Only in current shell | In current shell + subshells |
| Created with | VAR=value | export VAR=value or export VAR |
| Lifetime | Ends when shell exits | Ends when shell exits (but survives in child shells) |
| Examples | MYVAR, counter | PATH, HOME, USER, LANG |
Getting User Input in Shell
The read Command
- Syntax:
| |
- Reads one line of input from the user and stores it into a variable.
- If no variable is provided, input goes into the built-in variable
REPLY.
Basic Example:
| |
Using REPLY (Default Variable)
If no variable is given:
| |
Prompting Without echo (Using -p)
Instead of writing a separate echo, you can directly prompt:
| |
Silent Input (For Passwords) with -s
Doesn’t display what the user types.
| |
Multiple Inputs in One Line
You can read multiple values at once:
| |
Useful Options Summary
| Option | Meaning |
|---|---|
-p | Prompt inline |
-s | Silent (hide input) |
-t N | Timeout after N seconds |
-n N | Read N characters only |
-a | Store words into array |
Rule of Thumb
- Use
read -pfor interactive scripts. - Use
read -sfor sensitive info. - Combine options for flexibility.
Positional Parameters
What are Positional Parameters?
- Arguments passed to a script or program from the command line are called positional parameters.
- They are referenced by numbers (
$1,$2,$3, …). - Each argument is separated by spaces (default IFS = Internal Field Separator).
Example:
| |
$0→ script name (./myscript.sh)$1→ first argument (file.txt)$2→ second argument (dir1)$3→ third argument (192.168.1.1)
Accessing Positional Parameters
$ngives the nth argument.{}is required for arguments after$9.$9→ ninth argument${10}→ tenth argument${11}→ eleventh argument
Default Values for Parameters
If a parameter is missing, you can provide a default value with syntax:
| |
Example:
| |
- If
$1is given → it prints the actual argument. - If
$1is missing → it prints"ABC".
4. $0 Special Parameter
$0→ the name of the script as it was invoked.- Useful for script self-identification.
Example Script: Displaying Positional Parameters
| |
Run:
| |
Output:
| |
Practical Example: Display and Compress Script
| |
What Are Special Parameters?
- Special parameters are variables provided by the shell that hold important information.
- You cannot assign values to them, only read them.
Common Special Parameters
$0
- Expands to the name of the shell script being executed.
- Example:
| |
Output:
Script name is ./myscript.sh$#
- Expands to the number of positional parameters (arguments) passed to the script.
- Example:
| |
Output:
Arguments count: 3$@ and $*
- Both expand to all positional parameters.
- Subtle difference when quoted:
| Expression | Behavior |
|---|---|
$@ | Expands each argument as a separate word. Useful in loops. |
$* | Expands all arguments as a single word (joined with IFS, default is space). |
Example:
| |
$?
- Expands to the exit status of the most recent command.
0= success, non-zero = error.
Example:
| |
$$
- Expands to the process ID (PID) of the current shell.
- In a subshell, it still expands to the PID of the invoking shell (not the subshell).
Example:
| |
Exit Status Convention ($?)
- Every command returns a status code:
0→ success- Non-zero → error
Examples:
| |
Quick Summary Table
| Parameter | Meaning |
|---|---|
$0 | Name of the script |
$# | Number of arguments |
$@ | All arguments (each separately, preserves quoting) |
$* | All arguments (as a single word) |
$? | Exit status of last command |
$$ | PID of current shell |
Rule of Thumb
- Use
$0for script name,$#to check argument count,$@for iterating arguments,$?to check success/failure, and$$for PID when scripting background tasks or logs.
# $@ vs $* in Shell Scripting
Both $@ and $* expand to all positional parameters ($1, $2, $3, …).
The key difference appears when they are quoted.
$@ (All Positional Parameters)
- Expands to all arguments starting from
$1. - Unquoted
$@→ behaves like$1 $2 $3 …. - Quoted
"$@"→ preserves each argument as a separate quoted string.- Equivalent to
"$1" "$2" "$3" …. - Prevents word splitting inside arguments.
- Equivalent to
Example:
| |
Run:
| |
Output:
| |
Note: Each argument remains intact, even with spaces.
$* (All Positional Parameters)
- Expands to all arguments as a single string.
- Unquoted
$*→ same as unquoted$@→$1 $2 $3 …(word splitting occurs). - Quoted
"$*"→ treats all parameters as one single string, joined together.- The separator used is the first character of IFS (Internal Field Separator).
- By default, IFS = space, so arguments are joined with spaces.
Example:
| |
Run:
| |
Output:
| |
All arguments combined into one string.
Word Splitting Issue Example
| |
Run:
| |
- Without quotes, $@ = my file.txt your report.txt his document.txt
- This causes 6 files to be created instead of 3 (my, file.txt, yourreport, txt, …).
Fix with quoting:
| |
Now only 3 files are created correctly.