Bash脚本开发:实现指定时间区间内HH:MM格式时间生成
Fixing Your Bash Script to Output Minute-by-Minute Time Intervals
Hey there! Let's get your script working properly so it can take two HH:MM time arguments (like sh run.sh 03:40 05:40) and print every minute in that interval. Your current code has a few logic gaps and doesn't handle command-line input as you intended, so let's walk through the fixes and a better approach.
First, Let's Break Down the Problems in Your Original Code
- It uses interactive input (
readprompts) instead of accepting command-line arguments, which doesn't match your requested usage - The nested loop logic is flawed: when the current hour isn't the end hour, you should loop up to 59 minutes, not the end minute (this caused early stops in non-final hours)
- No handling for leading zeros (e.g.,
3:4won't format to03:04) - Bash treats numbers starting with
0as octal, so times like08:09would throw errors - No support for cross-day intervals (like
23:50to00:10)
Here's the Fixed, Fully Functional Script
#!/bin/bash # Check if we got exactly 2 arguments if [ $# -ne 2 ]; then echo "Usage: $0 <start-time-HH:MM> <end-time-HH:MM>" exit 1 fi # Split the input times into hours and minutes IFS=':' read -r from_hr from_min <<< "$1" IFS=':' read -r to_hr to_min <<< "$2" # Convert times to total minutes since midnight (avoids messy nested loops) # Use 10# to force base-10, so octal errors with 08/09 don't happen start_total=$((10#$from_hr * 60 + 10#$from_min)) end_total=$((10#$to_hr * 60 + 10#$to_min)) # Handle cross-day intervals (start time is later than end time, e.g., 23:50 to 00:10) if [ "$start_total" -gt "$end_total" ]; then end_total=$((end_total + 1440)) # Add 1 day's worth of minutes fi # Loop through each minute and print formatted time current_total="$start_total" while [ "$current_total" -le "$end_total" ]; do # Calculate current hour and minute, wrap around 24h for cross-day current_hr=$((current_total / 60 % 24)) current_min=$((current_total % 60)) # Print with leading zeros for HH:MM format printf "%02d:%02d\n" "$current_hr" "$current_min" # Move to next minute current_total=$((current_total + 1)) done
Key Improvements Explained
- Command-Line Argument Handling: Checks for the correct number of inputs first, then splits the HH:MM strings into hours/minutes using
IFS=':' - Total Minutes Conversion: Converting times to total minutes since midnight simplifies the loop logic—no more nested loops to handle hour rollovers!
- Octal Fix: The
10#prefix ensures Bash treats numbers like08as base-10 instead of octal (which would cause errors) - Cross-Day Support: Automatically handles intervals that wrap midnight by adding a full day's minutes to the end time
- Proper Formatting:
printf "%02d"ensures hours and minutes are always two digits (so3:5becomes03:05)
How to Use It
Run the script with your start and end times:
sh run.sh 03:40 05:40
You'll get output like this:
03:40 03:41 ... 05:39 05:40
This approach is cleaner, more robust, and fits exactly what you're looking for. Let me know if you need any clarification on any part!
内容的提问来源于stack exchange,提问作者PSYDUCK
相关产品推荐
相关产品推荐

