作者rickieyang (Rickie Yang)
看板Linux
标题Re: [问题] shell浮点数运算问题
时间Tue Dec 4 23:26:17 2018
忍不住回一下...
※ 引述《zchien (小建)》之铭言:
: 我用unix 系统
UNIX的商标权由国际开放标准组织所拥有
只有符合单一UNIX规范的UNIX系统才能使用UNIX这个名称
否则只能称为类UNIX(UNIX-like)。
既然你来到这个版, 我猜你是用 Linux, 就直接说用 Linux 吧
: 写sh时,遇到了一个bug ,就是浮点数无法运算
我猜你的意思是 写 shell script.
: 我使用ntpdate去校正时间, 并且记录校正了多少时间
: 例如:需要校正的时间是 0.000304 s
: 我写
: ntpdate -p 10.37.82.23 > time.txt
不知道你是用哪一个系统?
Linux 用 ntpdate -p 10.37.82.23 应该会报错吧?!
usage: ntpdate [-46bBdqsuv] [-a key#] [-e delay] [-k file] [-p samples] \
[-o version#] [-t timeo] server ...
或是你是指 ntpdate
-q 10.37.82.23 ?
: NTP= grep delay time.txt | awk ' ' {print $6}
上面的语法应该也会报错吧?
NTP=$(grep delay time.txt | awk '{print $6}')
: # $NTP will show 类似 0.000304
: if [ $NTP -le 0.100001 ];then
: ntpdate -u 10.37.82.23
: fi
先不管 能不能用小数点的问题.
为什麽 小於等於 0.100001 秒才更新?
如果 offset 大於 0.100001 秒就不更新?
: # 如果NTP server 连线异常, $NTP will show 0.000000
: if [ $NTP -eq 0.000000 ];then
: echo "NTP server not connect"
: fi
: 上面第一个if 会 不成立 , 可能类似浮点数运算, 他以为两个都是0
: 第二个if 也会显示错误, [0.000000 -eq 0.000000 ] 他竟然显示不相等
: 请问这是什麽原因,我可以怎麽修正
应该不会是不成立或是不相等吧?
-eq 应该会直接骂人, 类似:
./test.sh: line n: [: 0.000000: integer expression expected
首先, 既然你是用 > time.txt, 会一直被覆盖, 所以假设 time.txt 并没有要保留.
那其实可以直接一路 | 到底
NTP=$(ntpdate -q 10.37.82.23 | grep delay | awk '{print $6}')
然後都已经用 awk 了, 可以不用特别再叫 grep 出来跑龙套
NTP=$(ntpdate -q 10.37.82.23 | awk '/delay/{print $6}')
另外, 不知道你有没有发现, 这样你得到的 NTP 後面其实会有一个
,
$ ntpdate -q clock.stdtime.gov.tw
server 211.22.103.158, stratum 2, offset 0.000697
, delay 0.03252
4 Dec 22:41:21 ntpdate[1947]: adjust time server 211.22.103.158 offset 0.000697 sec
这应该会影响你後面的判断式
把它去掉比较好一些
NTP=$(ntpdate -q 10.37.82.23 | awk '/delay/{print $6}'|sed -e 's/,$//')
或是可以在 awk print 时先乘 1000000, 然後往後都可以用 us(微秒) 来处理
这样 awk 会自己把 , 去掉, 也间接避开了小数点运算的限制
NTP=$(ntpdate -q 10.37.82.23 | awk '/delay/{print $6*1000000}')
if [ "$NTP" -le "100001" ];then
ntpdate -u 10.37.82.23
fi
if [ "$NTP" -eq "0" ];then
echo "NTP server not connect"
fi
先不管不能判断小数点, 逻辑判断上 0.000000 也是 -le 0.100001 呀...
把两个 if 合在一起吧.
NTP=$(ntpdate -q 10.37.82.23 | awk '/delay/{print $6*1000000}')
if [ "$NTP" -eq "0" ];then
echo "NTP server not connect"
elif [ "$NTP" -le "100001" ];then
ntpdate -u 10.37.82.23
fi
虽然机率不比中乐透高, 有考虑过如果刚刚好 offset 是 0.000000 秒吗?
man ntpdate:
DIAGNOSTICS
ntpdate’s exit status is zero if it finds a server and updates the
clock, and nonzero otherwise.
ntpdate 有错误时的 return code 不是 0, 建议用这个来判断比较好.
#!/bin/sh
ntp_response=$(ntpdate -q 10.37.82.23 2>&1)
rc=$?
if [ "${rc}" -ne "0" ];then
echo "ntpdate error, return code: ${rc}"
else
ntp_offset=$(echo ${ntp_response} | awk '/delay/{print $6*1000000}')
if [ "${ntp_offset}" -le "100001" ];then
echo "offset: ${ntp_offset}"
ntpdate -u 10.37.82.23
fi
fi
大概是酱~
最後有两个问题还是不解.
1. 为什麽 offset -le 0.100001 才要 -u, 超过 0.100001 不处理吗?
2. 有考虑直接改用 ntpd 吗?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 220.133.28.48
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Linux/M.1543937183.A.3AC.html
※ 编辑: rickieyang (220.133.28.48), 12/04/2018 23:30:15
1F:推 kdjf: 看以前发的文很可能是solaris系列,所以参数之类不同不奇怪 12/05 00:57
2F:推 zchien: 感谢回覆,solaris和你上面指令应该相同,很多指令都是硬 12/05 23:35
3F:→ zchien: 记的,所以上面可能写的不完全,明天上班,我在试看看,感 12/05 23:35
4F:→ zchien: 恩 12/05 23:35
5F:推 zchien: Server上面有跑程式,如果时间瞬间差太大,程式会当机, 12/05 23:43
6F:→ zchien: 所以写crontab 让他每小时校时 12/05 23:43
7F:→ kdjf: 那就更适合ntpd,他本身就考虑到时间不能突然跳动的问题了 12/06 01:22
8F:→ kdjf: 只是你系统上不一定有现成的 12/06 01:23
9F:→ rexsony: 喔喔,高手过招果然很多学习的主体地方 12/06 18:18
10F:推 jamselee: 版上高手好多 12/10 07:16
11F:推 TPPCMAN: 这是 高手高手高高手了吧 12/12 11:31