Week 01 Assignment¶
Apply everything from Week 01 in a single cohesive project: a file inventory script that explores the filesystem, processes text, and produces a report.
Overview¶
You will write a script called inventory.sh that:
- Accepts a directory as a command-line argument (default: current directory)
- Scans the directory recursively
- Produces a report showing:
- Total number of files and directories
- Disk usage summary
- Top 5 file types by count (based on extension)
- Top 5 largest files
- Files modified in the last 7 days
- Saves the report to a file and prints it to the terminal
Requirements¶
Your script must demonstrate:
| Skill | How |
|---|---|
| Variables | Store directory path, counts, timestamps |
| Control flow | Validate directory argument |
| Loops | Iterate over files |
| Text processing | awk, sort, uniq for statistics |
| I/O redirection | tee to write and display simultaneously |
find |
File discovery and filtering |
| Parameter expansion | Extract file extensions |
| Functions | At least 3 named functions |
Starter Template¶
#!/usr/bin/env bash
set -euo pipefail
TARGET="${1:-.}"
REPORT="/tmp/inventory_$(date +%Y%m%d_%H%M%S).txt"
usage() {
echo "Usage: $0 [DIRECTORY]"
echo "Generate a file inventory report."
}
validate() {
[[ -d "$TARGET" ]] || { echo "Error: '$TARGET' is not a directory" >&2; exit 1; }
}
count_items() {
echo "=== File Counts ==="
echo "Files: $(find "$TARGET" -type f | wc -l)"
echo "Directories: $(find "$TARGET" -type d | wc -l)"
echo "Symlinks: $(find "$TARGET" -type l | wc -l)"
}
top_extensions() {
echo "=== Top 5 File Types ==="
find "$TARGET" -type f -name "*.*" \
| awk -F. '{print $NF}' \
| tr '[:upper:]' '[:lower:]' \
| sort | uniq -c | sort -rn | head -5
}
largest_files() {
echo "=== Top 5 Largest Files ==="
find "$TARGET" -type f -printf "%s\t%p\n" \
| sort -rn | head -5 \
| awk '{printf "%10d bytes %s\n", $1, $2}'
}
recent_files() {
echo "=== Files Modified in Last 7 Days ==="
find "$TARGET" -type f -mtime -7 -printf "%TY-%Tm-%Td %p\n" | sort -r | head -20
}
main() {
[[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && { usage; exit 0; }
validate
{
echo "======================================"
echo " File Inventory Report"
echo " Directory: $(realpath "$TARGET")"
echo " Generated: $(date '+%Y-%m-%d %H:%M:%S')"
echo "======================================"
echo ""
count_items
echo ""
top_extensions
echo ""
largest_files
echo ""
recent_files
echo ""
echo "Report saved to: $REPORT"
} | tee "$REPORT"
}
main "$@"
Grading Criteria¶
| Criterion | Points |
|---|---|
| Script runs without errors | 20 |
| Correct argument handling (default, missing, invalid) | 15 |
| At least 3 functions | 15 |
| Report contains all 5 sections | 20 |
| Output written to both terminal and file | 10 |
shellcheck passes with no warnings |
20 |
| Total | 100 |
Stretch Challenges¶
- Add
--jsonflag that outputs the report as JSON (usingprintfwith manual JSON construction). - Add
--compare DIR2that shows files in DIR1 not in DIR2 and vice versa. - Add color output for warnings (disk usage > 80%, files > 100MB).
- Make the report email itself using
mailorsendmailif a--emailflag is passed.
Submission¶
- Submit
inventory.shto theassignments/directory in the course repository. - Include a comment block at the top with your name and a brief description.
- Run
shellcheck inventory.shand include the (clean) output as a comment or in a README.