Week 1 Homework - Shell Scripting
Time estimate: 1.5 hours maximum
Submission: Create a directory week1-[netid] with your solutions and add it as a submodule to the class repo.
Setup
Create your homework directory:
mkdir week1-[netid]
cd week1-[netid]
All scripts should be executable (chmod +x script.sh) and include a proper shebang (#!/usr/bin/env bash).
Exercise 1: Custom ls (15 minutes)
Read man ls and write an ls command that lists files with the following properties:
- Includes all files, including hidden files
- Sizes are in human-readable format (e.g.,
454Minstead of454279954) - Files are ordered by recency (most recently modified first)
- Output is colorized
Save your command in a file called ex1_command.txt.
Sample output:
-rw-r--r-- 1 user group 1.1M Jan 14 09:53 baz
drwxr-xr-x 5 user group 160 Jan 14 09:53 .
-rw-r--r-- 1 user group 514 Jan 14 06:42 bar
-rw-r--r-- 1 user group 106M Jan 13 12:12 foo
drwx------+ 47 user group 1.5K Jan 12 18:08 ..
Hint: Look for flags related to “all”, “human-readable”, “time”, and “color” in the man page.
Exercise 2: Semester Setup Script (20 minutes)
Write a bash script called semester that creates a directory structure for organizing coursework.
Requirements:
The script should:
- Take a semester name as an argument (e.g.,
fall2025) - Create the following directory structure:
fall2025/ ├── comp140/ ├── comp182/ ├── math212/ └── projects/ - Create a
README.mdfile in the root directory with:- The semester name
- The current date (use
date) - A placeholder for course descriptions
Example usage:
./semester fall2025
Expected output:
Created semester directory: fall2025
Created course directories: comp140, comp182, math212, projects
Created README.md
Bonus: Make the course names configurable via additional arguments.
Exercise 3: marco and polo (20 minutes)
Write two bash functions that work together for directory navigation:
marco- Saves the current working directorypolo- Returns you to the directory where you last executedmarco
Requirements:
- Create a file called
navigation.sh - Implement both functions
- The saved directory should persist across terminal sessions (hint: save to a file)
- If
polois called beforemarco, print a helpful error message
Example usage:
$ source navigation.sh
$ cd /usr/local/bin
$ marco
Saved current directory
$ cd ~
$ cd Documents
$ pwd
/home/user/Documents
$ polo
$ pwd
/usr/local/bin
Hint: You’ll need to save the directory to a file in your home directory (like ~/.marco_location).
Exercise 4: Retry Script (25 minutes)
Write a bash script called retry.sh that runs a command until it fails, then reports statistics.
The script should:
- Take another script as an argument
- Run it repeatedly until it exits with a non-zero status
- Capture both
stdoutandstderrto separate files - Report:
- Number of successful runs before failure
- The final error message
- Total time elapsed
Test it with this script (save as flaky.sh):
#!/usr/bin/env bash
n=$(( RANDOM % 100 ))
if [[ $n -eq 42 ]]; then
echo "Something went wrong"
>&2 echo "The error was using magic numbers"
exit 1
fi
echo "Everything went according to plan"
Example usage:
$ ./retry.sh ./flaky.sh
Run 1: success
Run 2: success
Run 3: success
...
Run 47: FAILED
Statistics:
- Successful runs: 46
- Failed on run: 47
- Total time: 2.3 seconds
Error output:
The error was using magic numbers
Standard output from failed run:
Something went wrong
Hints:
- Use a while loop with a counter
- Check
$?after each run - Use
date +%sto track time - Redirect output:
command > stdout.log 2> stderr.log
Exercise 5: HTML Archive Creator (20 minutes)
Write a command (can be a one-liner or script called archive_html.sh) that:
- Recursively finds all HTML files in the current directory
- Creates a tar.gz archive containing them
- Handles filenames with spaces correctly
- Names the archive with today’s date:
html_backup_YYYY-MM-DD.tar.gz
Requirements:
- Must work even if files have spaces in their names
- Should use
findcombined withxargsorfind -exec - Should create the archive in the current directory
Test setup:
mkdir -p test/web/{pages,styles}
touch test/web/index.html
touch test/web/pages/"about us.html"
touch test/web/pages/contact.html
touch test/web/styles/main.css
Expected result:
$ ./archive_html.sh
Found 3 HTML files
Created archive: html_backup_2025-01-20.tar.gz
Hints:
find . -name "*.html"finds HTML files- Use
find -print0withxargs -0for handling spaces - Or use
find -exec tar ... - Use
date +%Y-%m-%dfor the date format
Exercise 6: Log Analyzer (20 minutes)
Write a script called analyze_logs.sh that processes a log file and produces a summary report.
Given this sample log file (save as server.log):
2025-01-20 10:23:15 INFO Server started on port 8080
2025-01-20 10:23:18 INFO Connected to database
2025-01-20 10:24:32 WARNING High memory usage: 85%
2025-01-20 10:25:01 ERROR Failed to connect to redis
2025-01-20 10:25:15 INFO User login: alice@rice.edu
2025-01-20 10:26:42 ERROR Database timeout
2025-01-20 10:27:03 INFO User login: bob@rice.edu
2025-01-20 10:28:15 WARNING Disk space low: 5% remaining
2025-01-20 10:29:01 ERROR Connection refused
2025-01-20 10:30:12 INFO User login: charlie@rice.edu
Your script should output:
$ ./analyze_logs.sh server.log
Log Analysis Report
===================
Total lines: 10
INFO messages: 5
WARNING messages: 2
ERROR messages: 3
Most recent error:
2025-01-20 10:29:01 ERROR Connection refused
Unique users logged in: 3
Requirements:
- Use
grep,wc, and other text processing tools - Extract and count different log levels
- Find the most recent error
- Count unique user logins
Hints:
grep -c "pattern"counts matchestail -1gets the last line- Use
cutorawkto extract specific fields sort | uniq | wc -lcounts unique values
Exercise 7 (Bonus/Advanced): Recent File Finder (10 minutes)
Write a script or one-liner that finds and lists the most recently modified files in a directory tree.
Requirements:
- Recursively search from current directory
- Find the 10 most recently modified files
- Display: modification time, file size (human-readable), and file path
- Exclude hidden files and directories
Example output:
$ ./recent_files.sh
Jan 20 14:32 1.2M ./reports/analysis.pdf
Jan 20 14:15 456K ./data/results.csv
Jan 20 13:58 12K ./scripts/process.py
...
Hints:
- Use
findwith-type fand-mtime - Combine with
ls -lhtor usefind -printf - Use
headto limit results - May need to exclude paths matching
*/.*
Submission Checklist
Your week1-[netid] directory should contain:
week1-netid/
├── ex1_command.txt
├── semester
├── navigation.sh
├── retry.sh
├── flaky.sh (provided)
├── archive_html.sh
├── analyze_logs.sh
├── server.log (provided)
└── recent_files.sh (bonus)
Before submitting:
- Make all scripts executable:
chmod +x *.sh semester - Test each script works as described
- Add comments explaining tricky parts
- Run
shellcheckif available:shellcheck *.sh
Submit by: Adding your directory as a git submodule and pushing to your repo
Grading
- Exercises 1-4: Required (90%)
- Exercises 5-6: Required (10%)
- Exercise 7: Bonus (5% extra credit)
Remember: If any exercise takes more than the estimated time, stop and ask for help in office hours. The goal is learning, not frustration!
Tips
- Test incrementally - don’t write the whole script at once
- Use
echostatements to debug - Check exit codes:
echo $? - Quote your variables:
"$var"not$var - Read error messages carefully
- Use
shellcheckto catch common mistakes
Good luck, and remember: the best programmers are lazy programmers who automate everything!