Q1Which syntax uses the default access.log when no first argument is passed?
Log Summary Report — Arguments, Functions and Integration
This article is part of the Linux Course, where you master practical Linux skills from scratch, from basic commands through to shell scripting.
Take the target log with log=${1:-access.log}, aggregate it with a for loop plus grep -c and awk '{sum+=$1}', and wrap it all up in a here-doc report and an exit code — illustrated and practiced in a browser terminal.
Bringing the pieces into one script — the skeleton of a log summary report
Everything you've learned so far — variables, positional parameters ($1), conditionals ([ ] and if), loops (for / while), functions (name() { } and local), reading input (while read … done < file), command integration ($(...)), and output (>> and here-doc) — now comes together in one practical script.
The subject is the most common one in operations: a log summary report.
A practical script takes the target log and a threshold as arguments, checks the input, aggregates, gathers the results into a report, and finishes by returning an exit code.
For the aggregation, combine commands like grep for counts, awk for sums, and sed for formatting; pulling repeated work into functions and loops keeps it readable.
When a positional parameter is empty, fill it in with the default ${1:-access.log}.
vi mini.sh # open in the editor, write the following, and save with :wq
# #!/bin/sh
# log=${1:-access.log} # default when no argument is given
# count_status() { # function returning the count for a status code
# grep -c " $1\$" "$log"
# }
# if [ ! -f "$log" ]; then # input check
# echo "not found: $log" >&2
# exit 1
# fi
# for s in 200 403 500; do # aggregate per status code
# echo "$s : $(count_status $s)"
# done
# exit 0
chmod +x mini.sh
| Element | Where it is used in this script | Example |
|---|---|---|
Variable name=... | Keep the log name, destination, and threshold in one place | log=${1:-access.log} |
Argument $1 / ${1:-default} | Take the target log and threshold from the command line | limit=${2:-1} |
Condition [ -f f ] / if | Check the log exists and test whether the threshold is exceeded | if [ ! -f "$log" ]; then exit 1; fi |
Loop for / while read | Aggregate per status code and read one line at a time | for s in 200 403 500; do … done |
Function name() { … } | Group the aggregation under a name and reuse it | count_status() { grep -c " $1\$" "$log"; } |
Reading input while read … < f | Read the log line by line and count per URL | while read line; do … done < "$log" |
Integration $(grep -c …) / awk | Pull counts and sums in with command substitution | n=$(grep -c ' 500$' "$log") |
Output >> / here-doc | Write the aggregated values out as a fixed-format report | cat > "$out" <<REPORT … REPORT |
Read the input and finish with command integration — while read plus grep / awk / sed
Do the fine-grained, line-by-line work with while read line; do … done < file.
Wrap that in a function together with grep to narrow each line down, awk to total the columns, and sed to normalize the text, and you can reuse the same counting logic in other scripts.
Slip in formatting like sed 's/^GET /[GET] /' and the report's layout stays consistent.
To finish, embed the aggregated values in a fixed report with a here-doc, append a warning and return exit 1 when the threshold is exceeded, or return exit 0 when everything is fine.
Take the second argument as the threshold with ${2:-100} and compare numbers as in if [ "$err" -gt "$limit" ], and you get a pass/fail report you can use in operations.
The capstone of this course is using the `grep` / `awk` / `sed` you learned earlier inside a script's own control structures.
vi scan.sh # open in the editor, write the following, and save with :wq
# #!/bin/sh
# log=${1:-access.log}
# limit=${2:-1}
# err=$(grep -c ' 500$' "$log") # get the 500 count with integration
# while read line; do # read one line at a time
# echo "$line" | sed 's/^/log: /' # format and print
# done < "$log"
# if [ "$err" -gt "$limit" ]; then # check against the threshold
# echo "WARN: too many 500"; exit 1
# fi
# exit 0
chmod +x scan.sh
while read takes the lines in one at a time, and combining grep / awk / sed turns them into a report that flags problems.Passing or failing on a threshold argument — aggregation and exit codes together
Put the argument handling and counting from the earlier practices together with a pass/fail check and an exit code, and you have a report script you can actually run in operations.
Take the threshold from the first argument; when the count aggregated by grep -c or awk is at or above it, warn and return exit 1, and when it is below, treat it as normal and return exit 0.
The caller can tell success from failure by that exit code.
In numeric comparisons, -gt means "greater than" and -ge means "greater than or equal to", and that difference decides what happens to a value sitting exactly on the threshold.
Practice 2's [ "$err" -gt "$limit" ] is false when the count equals the threshold, while Practice 3's [ "$err" -ge "$limit" ] warns on an equal value too.
That is what settles the boundary case, so pick the one that fits your purpose.
-ge compares the aggregated count against the threshold: at or above it warns and returns exit 1, below it is normal and returns exit 0.Knowledge Check
Answer each question one by one.
Q2Which syntax reads a file one line at a time and processes it?
Q3How do you tell the caller something is wrong when the threshold is exceeded?