LiuShen

LiuShen / 通过HTTP同步时间

Last active 6 hours ago

Like 0

在123端口无法使用的情况下通过http请求头携带的时间实现时间同步

LiuShen revised this gist 6 hours ago · b233c4a

1 file changed, 78 insertions

sync-time.sh (file created)
@@ -0,0 +1,78 @@
1 + #!/bin/bash
2 +
3 + set -e
4 +
5 + URL="http://www.baidu.com/"
6 + COUNT=10
7 +
8 + echo "正在通过百度 HTTP 校准系统时间..."
9 + echo
10 +
11 + best_rtt=999999999
12 + best_time=0
13 +
14 + for i in $(seq 1 "$COUNT"); do
15 + start=$(date +%s%3N)
16 +
17 + headers=$(curl \
18 + --noproxy '*' \
19 + --connect-timeout 3 \
20 + --max-time 5 \
21 + -sS \
22 + -D - \
23 + -o /dev/null \
24 + "$URL" 2>/dev/null) || {
25 + echo "[$i/$COUNT] 请求失败"
26 + continue
27 + }
28 +
29 + end=$(date +%s%3N)
30 +
31 + date_header=$(printf '%s\n' "$headers" |
32 + grep -i '^Date:' |
33 + tail -n 1 |
34 + sed 's/^[Dd]ate:[[:space:]]*//')
35 +
36 + if [ -z "$date_header" ]; then
37 + echo "[$i/$COUNT] 未找到 Date 头"
38 + continue
39 + fi
40 +
41 + server_sec=$(date -u -d "$date_header" +%s 2>/dev/null) || {
42 + echo "[$i/$COUNT] 无法解析 Date: $date_header"
43 + continue
44 + }
45 +
46 + rtt=$((end - start))
47 + half_rtt=$((rtt / 2))
48 +
49 + # Date 头的时间 + 请求往返时间的一半
50 + estimated_ms=$((server_sec * 1000 + half_rtt))
51 +
52 + echo "[$i/$COUNT] RTT=${rtt}ms Date=$date_header"
53 +
54 + if [ "$rtt" -lt "$best_rtt" ]; then
55 + best_rtt=$rtt
56 + best_time=$estimated_ms
57 + fi
58 + done
59 +
60 + if [ "$best_time" -eq 0 ]; then
61 + echo
62 + echo "错误:无法从百度获取时间"
63 + exit 1
64 + fi
65 +
66 + echo
67 + echo "最佳 RTT: ${best_rtt}ms"
68 +
69 + before=$(date '+%Y-%m-%d %H:%M:%S.%3N')
70 +
71 + # 设置系统时间
72 + date -u -s "@$(awk "BEGIN {printf \"%.3f\", $best_time / 1000}")" >/dev/null
73 +
74 + after=$(date '+%Y-%m-%d %H:%M:%S.%3N')
75 +
76 + echo "校时前: $before"
77 + echo "校时后: $after"
78 + echo "校时完成。"