Unit 3: Bash Scripting Fundamentals - Subjective Questions
CSC104 — It Fundamentals • Practice Questions with Detailed Answers
20 questions
Define Bash scripting. Explain its purpose and list the basic steps required to create and execute a Bash script.
Bash scripting is the process of writing a sequence of commands in a text file that is interpreted and executed by the Bash shell.
Purpose:
- Automates repetitive command-line tasks.
- Combines multiple commands into a single program.
- Supports variables, decisions, loops, and functions.
- Helps perform system administration, file processing, and software deployment tasks.
Steps to create and execute a script:
- Create a file:
touch example.sh - Add the shebang as the first line:
#!/bin/bash - Write commands, such as
echo "Hello". - Make the file executable:
chmod +x example.sh - Execute it using
./example.sh.
A script can also be executed without changing its permissions by running bash example.sh.
Describe the standard structure of a Bash script and write a basic Hello World script.
A Bash script generally contains the following parts:
- Shebang: Identifies the interpreter that should execute the file.
- Comments: Document the purpose and logic of the script.
- Variables: Store values used by commands.
- Commands and control structures: Perform the required operations.
- Exit statement: Optionally returns an explicit status to the calling process.
Example:
#!/bin/bash
# A basic Hello World script
message="Hello, World!"
echo "$message"
exit 0Here, #!/bin/bash selects Bash, the line beginning with # is a comment, message is a variable, echo displays its value, and exit 0 indicates successful execution.
Explain how variables are declared, assigned, expanded, and removed in Bash. Distinguish between local, shell, and environment variables.
A Bash variable is created by assigning a value without spaces around =:
name="Asha"
age=20
echo "$name is $age years old"
unset agename="Asha"assigns a string.$nameor${name}expands the variable.- Double quotes preserve the value as one argument and still allow expansion.
- Single quotes prevent expansion, so
'$name'is displayed literally. unset ageremoves the variable.
Types of variables:
- Shell variable: Available in the current shell but not automatically inherited by child processes, for example
course="IT". - Environment variable: Exported to child processes using
export courseorexport course="IT". - Local variable: Restricted to a function when declared with
local, for examplelocal result=10.
Command substitution can assign command output: today=$(date).
Write and explain a Bash script that accepts a user's name and age through keyboard input and prints a formatted message.
The read command accepts input from standard input.
#!/bin/bash
read -r -p "Enter your name: " name
read -r -p "Enter your age: " age
echo "Hello, $name. You are $age years old."Explanation:
readstores input in a variable.-pdisplays a prompt before accepting input.-rprevents backslashes in the input from being treated as escape characters.nameandageare the destination variables.- Double quotes allow
$nameand$ageto be expanded while preserving spaces in the entered name.
For hidden input such as a password, read -s -p "Password: " password can be used. A following echo should be added to move the cursor to a new line.
Explain the purpose of comments in Bash. Distinguish between a shebang, a single-line comment, and a common technique for writing multi-line comments.
Comments document a script's purpose, assumptions, and complex logic. Bash ignores comments during normal execution.
- Shebang:
#!/bin/bashappears on the first line and tells the operating system which interpreter should execute the script. Although it begins with#, it has a special purpose. - Single-line comment: Any ordinary text following
#is ignored, unless the#is quoted or used in a special expansion.
bash
Calculate the final total
total=$((price + tax)) # Inline comment
Bash has no dedicated multi-line comment syntax. A no-operation command with a here-document is sometimes used:
: <<'COMMENT'
This block is ignored by the no-operation command.
It can serve as temporary documentation.
COMMENTUsing separate # lines is usually clearer for permanent documentation.
Describe positional arguments and special argument-related parameters in Bash. Write a script that displays the script name, first two arguments, argument count, and all arguments.
Arguments supplied after a script name are stored in positional parameters.
$0: Name or path used to invoke the script.$1,$2, and so on: Individual arguments.${10}: The tenth argument; braces are required for positions above 9.$#: Number of positional arguments."$@": All arguments, preserving each as a separate value."$*": All arguments combined according to the first character ofIFSwhen quoted.shift: Removes$1and moves the remaining arguments one position left.
#!/bin/bash
echo "Script: $0"
echo "First: ${1:-not provided}"
echo "Second: ${2:-not provided}"
echo "Count: $#"
printf 'Argument: %s\n' "$@"For ./show.sh red "dark blue", the count is 2, and "dark blue" remains one argument because it was quoted.
Explain indexed arrays and associative arrays in Bash. Demonstrate creation, access, update, traversal, and deletion.
Indexed arrays use numeric indexes beginning conventionally at 0:
colors=("red" "green" "blue")
echo "${colors[1]}"
colors[1]="yellow"
colors+=("black")
for color in "${colors[@]}"; do
echo "$color"
done
unset 'colors[0]'${colors[1]}accesses one element.${colors[@]}expands all elements separately.${#colors[@]}gives the number of stored elements.${!colors[@]}gives the indexes.
Associative arrays use string keys and must be declared:
declare -A marks
marks[Sam]=85
marks[Rita]=92
echo "${marks[Rita]}"
for student in "${!marks[@]}"; do
echo "$student: ${marks[$student]}"
done
unset 'marks[Sam]'Quoting array expansions is important because elements may contain spaces or wildcard characters.
What is string slicing in Bash? Explain how substrings, string length, prefix removal, and replacement are performed using parameter expansion.
String slicing extracts part of a string without calling an external command.
text="BashScripting"
echo "${#text}" # Length: 13
echo "${text:0:4}" # Bash
echo "${text:4}" # Scripting
echo "${text: -3}" # ing
echo "${text#Bash}" # Scripting
echo "${text/Scripting/Shell}" # BashShellMain forms:
${variable:offset:length}extractslengthcharacters fromoffset.${variable:offset}extracts from the offset to the end.${#variable}returns the string length.${variable#pattern}removes the shortest matching prefix.${variable##pattern}removes the longest matching prefix.${variable%pattern}and${variable%%pattern}remove matching suffixes.${variable/pattern/replacement}replaces the first match.${variable//pattern/replacement}replaces all matches.
A space is commonly placed before a negative offset, as in ${text: -3}, so Bash does not confuse it with the :- default-value operator.
Explain Bash file conditional expressions. Write an if statement that checks whether a supplied path is a readable regular file, a directory, or a nonexistent path.
File conditional expressions inspect paths and file properties.
Common tests include:
-e path: The path exists.-f path: It is a regular file.-d path: It is a directory.-r path: It is readable.-w path: It is writable.-x path: It is executable or searchable.-s path: It exists and has a size greater than zero.file1 -nt file2:file1is newer thanfile2.
#!/bin/bash
path=$1
if [[ -f $path && -r $path ]]; then
echo "Readable regular file"
elif [[ -d $path ]]; then
echo "Directory"
elif [[ ! -e $path ]]; then
echo "Path does not exist"
else
echo "Path exists but does not match the listed conditions"
fi[[ ... ]] is preferred for Bash scripts because it provides safer handling of expansions and supports compound expressions such as && and ||.
Compare string and arithmetic conditional expressions in Bash. Give suitable examples of each.
String conditions are commonly evaluated with [[ ... ]]:
[[ $a == $b ]]: Strings are equal.[[ $a != $b ]]: Strings differ.[[ -z $a ]]: String is empty.[[ -n $a ]]: String is nonempty.[[ $a < $b ]]: Lexicographic comparison.[[ $a == *.txt ]]: Pattern matching.
if [[ -n $username && $role == "admin" ]]; then
echo "Valid administrator"
fiArithmetic conditions are conveniently evaluated with (( ... )):
==,!=: Equality and inequality.<,<=,>,>=: Numeric comparisons.&&,||,!: Logical operators.
if (( score >= 40 && score <= 100 )); then
echo "Pass"
fiInside (( ... )), variable names usually do not require $. Arithmetic evaluation returns success when the resulting numeric expression is nonzero and failure when it is zero. Numeric input should still be validated when it comes from an untrusted source.
Define exit status in Bash. Explain how $?, exit, &&, ||, and ! use command success or failure.
Every command returns an integer exit status when it finishes:
0conventionally means success.- A nonzero value conventionally means failure or a specific error.
- Bash exit statuses are normally in the range 0 to 255.
$? contains the status of the most recently completed foreground pipeline:
mkdir reports
status=$?
echo "Status: $status"The value should be stored immediately because another command changes $?.
A script can return an explicit status:
if [[ ! -f $1 ]]; then
echo "File not found" >&2
exit 1
fi
exit 0Conditional command lists:
command1 && command2runscommand2only ifcommand1succeeds.command1 || command2runscommand2only ifcommand1fails.! commandlogically reverses the command's status.
Scripts should return meaningful nonzero statuses so callers can detect and handle failures.
Write a Bash script using if, elif, and else to classify an integer as positive, negative, or zero. Explain the control flow.
#!/bin/bash
read -r -p "Enter an integer: " number
if [[ ! $number =~ ^-?[0-9]+$ ]]; then
echo "Invalid integer" >&2
exit 1
elif (( number > 0 )); then
echo "Positive"
elif (( number < 0 )); then
echo "Negative"
else
echo "Zero"
fiControl flow:
ifevaluates the first condition.=~tests the input against a regular expression before arithmetic evaluation.- If the input is invalid, an error is written to standard error and the script terminates.
- Each
elifis tested only when all preceding conditions are false. elsehandles the remaining case, which is zero.ficloses the conditional statement.
Only the commands belonging to the first true branch are executed.
Explain the case statement in Bash. Write a menu-driven example and compare it with an if-elif-else statement.
A case statement compares one value against a sequence of shell patterns. It is well suited to menus, command options, and grouped string choices.
#!/bin/bash
read -r -p "Choose start, stop, restart, or quit: " action
case $action in
start)
echo "Starting service"
;;
stop)
echo "Stopping service"
;;
restart|reload)
echo "Reloading service"
;;
quit|q)
echo "Exiting"
;;
*)
echo "Unknown choice" >&2
exit 1
;;
esac- Each pattern ends with
). |combines alternative patterns.*is the default pattern.;;ends a branch.esaccloses the statement.
case is usually clearer than a long if-elif-else chain when one value is matched against several patterns. if is more suitable for unrelated, numeric, file, or compound Boolean conditions.
Compare for, while, and until loops in Bash. Provide an example of each and state when each form is appropriate.
for loop: Iterates over a known list of values.
for file in *.txt; do
echo "$file"
doneIt is suitable for arguments, files, arrays, and numeric sequences. A C-style form such as for ((i=1; i<=5; i++)) is also available.
while loop: Repeats while a command or condition succeeds.
count=1
while (( count <= 3 )); do
echo "$count"
((count++))
doneIt is appropriate when repetition depends on a condition or when reading input, for example while IFS= read -r line.
until loop: Repeats while a condition fails and stops when it becomes successful.
count=1
until (( count > 3 )); do
echo "$count"
((count++))
doneuntil is useful when the desired stopping condition is easier to express positively. Every condition-controlled loop must eventually change the relevant state to avoid an unintended infinite loop.
Distinguish between break and continue in Bash loops. Explain their behavior in nested loops with examples.
break terminates a loop immediately, while continue skips the remainder of the current iteration and starts the next one.
for ((i=1; i<=10; i++)); do
if (( i == 3 )); then
continue
fi
if (( i == 7 )); then
break
fi
echo "$i"
doneThis prints 1, 2, 4, 5, and 6. The value 3 is skipped, and the loop ends when the value becomes 7.
In nested loops:
breakaffects the innermost loop by default.break 2exits two nested loop levels.continue 2continues with the next iteration of the loop two levels outward.
for row in 1 2 3; do
for column in 1 2 3; do
[[ $row == 2 && $column == 2 ]] && break 2
echo "$row,$column"
done
doneThe numbered forms should be used carefully because they can make deeply nested control flow harder to understand.
Explain how functions are defined and called in Bash. Describe function arguments, local variables, output, and return status with an example.
A function groups reusable commands under a name.
calculate_sum() {
local first=$1
local second=$2
local total=$((first + second))
printf '%s\n' "$total"
}
if result=$(calculate_sum 8 12); then
echo "Sum: $result"
else
echo "Calculation failed" >&2
fiKey points:
- The function is called using its name followed by arguments.
- Inside the function,
$1,$2,$#, and"$@"refer to the function's arguments. localprevents variables from unintentionally changing variables outside the function.- A function can produce data through standard output, which can be captured with command substitution.
return nsupplies an exit status, not a general string or large numeric result.- If
returnis omitted, the function's status is the status of its last command.
Functions improve reuse, readability, testing, and separation of responsibilities.
Describe practical methods for debugging a Bash script. Explain syntax checking, execution tracing, strict-mode options, and diagnostic output.
Useful Bash debugging methods include:
- Syntax checking:
bash -n script.shparses the script without executing normal commands. - Execution tracing:
bash -x script.shprints expanded commands before executing them. - Selective tracing: Use
set -xto start tracing andset +xto stop it. - Verbose mode:
bash -v script.shdisplays shell input lines as they are read. - Diagnostic output: Use
printf 'value=%q\n' "$value" >&2to inspect values without mixing diagnostics with normal output. - Exit-status checks: Store
$?immediately or place a command directly in anifcondition.
Common defensive settings are:
set -euo pipefail-eexits in many contexts when an unhandled command fails.-ureports the use of unset variables.pipefailmakes a pipeline fail if any component fails.
These options have contextual exceptions, so they do not replace explicit error handling. Tools such as shellcheck can also detect quoting errors, unused variables, and other common problems.
Explain useful Bash shortcuts and command-line editing features that improve efficiency.
Bash provides keyboard and history shortcuts that reduce repeated typing.
Common editing shortcuts:
Ctrl+A: Move to the beginning of the command line.Ctrl+E: Move to the end of the command line.Ctrl+U: Delete from the cursor to the beginning.Ctrl+K: Delete from the cursor to the end.Ctrl+W: Delete the word before the cursor.Ctrl+R: Search command history interactively.Ctrl+C: Interrupt the current command.Ctrl+L: Clear and redraw the terminal screen.Tab: Complete command names, paths, and other supported values.
History expansions:
!!: Reuse the previous command.!n: Reuse history entry numbern.!text: Reuse the most recent command beginning withtext.
History expansion should be reviewed before execution, especially when combined with privileged commands. history, arrow-key navigation, tab completion, and searchable history are generally safer for complex commands.
Explain how to create custom commands and aliases in Bash. Distinguish between temporary and persistent definitions.
An alias defines a short replacement for command text:
alias ll='ls -alF'
alias gs='git status'These definitions are temporary when entered directly in a terminal and disappear when that shell session ends. View aliases with alias and remove one with unalias ll.
Aliases are suitable for short substitutions but do not handle arguments flexibly. A function is better for parameterized behavior:
mkcd() {
mkdir -p -- "$1" && cd -- "$1"
}A standalone executable script can also become a custom command:
- Create a script with a shebang.
- Grant execute permission using
chmod +x script-name. - Place it in a directory such as
$HOME/binor$HOME/.local/bin. - Ensure that directory appears in
PATH.
For persistence, aliases, functions, and PATH updates can be added to a Bash startup file such as ~/.bashrc, then loaded with source ~/.bashrc.
Design a complete Bash script that creates a backup of a user-supplied file. The script must validate input, use a function, generate a timestamped filename, report errors, and return meaningful exit statuses.
#!/bin/bash
create_backup() {
local source_file=$1
local backup_dir=${2:-./backups}
local timestamp
local base_name
local destination
timestamp=$(date '+%Y%m%d_%H%M%S') || return 3
base_name=${source_file##*/}
destination="$backup_dir/${base_name}.${timestamp}.bak"
mkdir -p -- "$backup_dir" || {
echo "Cannot create backup directory" >&2
return 4
}
cp -- "$source_file" "$destination" || {
echo "Backup copy failed" >&2
return 5
}
echo "Backup created: $destination"
}
if (( $# < 1 || $# > 2 )); then
echo "Usage: $0 FILE [BACKUP_DIRECTORY]" >&2
exit 2
fi
if [[ ! -f $1 || ! -r $1 ]]; then
echo "Input must be a readable regular file" >&2
exit 1
fi
create_backup "$1" "${2:-./backups}"
exit $?Explanation:
- Positional arguments provide the source file and optional backup directory.
${2:-./backups}supplies a default directory.- File conditions reject missing, non-regular, or unreadable input.
- A function keeps backup logic separate from argument validation.
datecreates a timestamp, and${source_file##*/}extracts the base filename.- Quoted expansions preserve spaces and prevent unwanted pathname expansion.
--protects commands from filenames beginning with-.- Distinct nonzero statuses identify usage, input, timestamp, directory, and copy failures.
Define Bash scripting. Explain its purpose and list the basic steps required to create and execute a Bash script.
Bash scripting is the process of writing a sequence of commands in a text file that is interpreted and executed by the Bash shell.
Purpose:
- Automates repetitive command-line tasks.
- Combines multiple commands into a single program.
- Supports variables, decisions, loops, and functions.
- Helps perform system administration, file processing, and software deployment tasks.
Steps to create and execute a script:
- Create a file:
touch example.sh - Add the shebang as the first line:
#!/bin/bash - Write commands, such as
echo "Hello". - Make the file executable:
chmod +x example.sh - Execute it using
./example.sh.
A script can also be executed without changing its permissions by running bash example.sh.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →