如何修改Bash循环确保同一时间仅执行一个NTP同步请求?
Got it, let's tackle this problem. Your current script uses a fixed 30-second sleep, but if ntpdate ever takes longer than that to run (or if the script gets accidentally restarted mid-sync), you end up with multiple concurrent NTP requests hitting the pool and triggering those annoying rate limits. Here are a couple of solid ways to make sure only one sync runs at a time:
First: Add a File Lock to Prevent Duplicate Script Instances
Your original script runs syncs sequentially (it waits for each ntpdate to finish before sleeping), but the issue likely comes from multiple instances of the script running at once (maybe from accidental restarts during build setup). Adding a file lock fixes this:
Modified Script with Locking
#!/bin/bash -e # Define a lock file path (stores the running script's PID) LOCK_FILE="/tmp/ntp_sync_lock.lock" # Check if another instance is already active if [ -f "$LOCK_FILE" ]; then RUNNING_PID=$(cat "$LOCK_FILE") # Verify the PID is still a running process if ps -p "$RUNNING_PID" > /dev/null 2>&1; then echo "Another sync script instance is running (PID: $RUNNING_PID). Exiting." exit 1 else # Lock file exists but the process is dead—clean up the stale lock rm "$LOCK_FILE" fi fi # Write our current PID to the lock file echo $$ > "$LOCK_FILE" # Ensure the lock file gets deleted when the script exits (even if interrupted) trap 'rm -f "$LOCK_FILE"' EXIT INT TERM while true; do # Run the NTP sync—wait for it to fully complete before moving on sudo ntpdate -u de.pool.ntp.org >> ntpdate.txt # Wait 30 seconds only AFTER the sync finishes sleep 30 done
How This Works:
- Lock Check: On startup, the script verifies if a lock file exists. If it does and the PID inside is still active, it exits immediately to avoid duplicates.
- Cleanup Trap: The
trapcommand guarantees the lock file is removed if the script exits normally, gets interrupted withCtrl+C, or receives a termination signal—no stale locks left behind. - Strict Sequential Syncs: The
sleep 30only runs afterntpdatefinishes, so the next sync won't start until the previous one is done plus 30 seconds.
Bonus: Use macOS's Built-in NTP Daemon (Even Better!)
If you're open to ditching the custom script entirely, macOS has a native ntpd service designed for reliable time sync. It handles frequency automatically, avoids rate limits, and runs as a background daemon. Enable it with:
sudo systemsetup -setnetworktimeserver de.pool.ntp.org sudo systemsetup -setusingnetworktime on
This way macOS manages time correction for you—no need to maintain a custom script.
Simplify Your Kill Command
Your existing kill command can be cleaned up with pkill instead of parsing ps aux—it's far more concise:
pkill -f test.sh
This kills all processes matching the test.sh command without messy pipes.
内容的提问来源于stack exchange,提问作者mles

