实例:
脚本功能说明:
不断连接(然后立即断开)本地80端口;如果连接时间超过0.9s则输出连接时长并退出脚本
1 2 3 4 5 6 7 8 9 10 |
TIMEFORMAT="%E" i=0 while :; do ((i++)) t=$( ( time nc -vz 127.0.0.1 80 >/dev/null ) 2>&1) [[ $( echo "$t > 0.9"|bc) -eq 1 ]] && echo -e "`date`\t$i\t$t" && break if [[ $((i % 1000)) -eq 0 ]]; then echo -e "`date`\t$i" fi done |
- 通过TIMEFORMAT来设置time命令的输出,time命令的选项不走参数,走环境变量;具体格式man time
- nc -z选项的行为是,连接后立即断开,相当于扫描; -v选项输出扫描结果提示,这里面直接扔掉了,所以该选项是多余的;nc似乎没有连接超时的设置
- bash不支持浮点数的运算与比较,借助bc实现;对于比较运算,为真输出1,为假输出0; 和bc的返回值无关
- bash中支持模运算,上面也用到了
- time的输出是输出到标准错误的,一般情况下我们没法直接接收到标准错误的输出,这里就把time放到了一个子shell中执行,然后将子shell的标准错误重定向到标准输出,然后赋值给变量t;所以,需要注意一点的是,time前面的两个圆括号之间是有空格的,少了空格就成了算数运算了(结果必错)
上面脚本执行比较慢,如果是多核的话,可以稍微修改一下:(该脚本未测试,可能不好使)
1 2 3 4 5 6 7 8 9 10 11 12 |
TIMEFORMAT="%E" i=0 while :; do ( time nc -vz 127.0.0.1 80 >/dev/null ) 2>&1 done|while read t; do ((i++)) [[ $( echo "$t > 0.9"|bc) -eq 1 ]] echo -e "`date`\t$i\t$t" && break if [[ $((i % 1000)) -eq 0 ]]; then echo -e "`date`\t$i" fi done |
相关参考: http://blog.csdn.net/gengshenghong/article/details/7583580
上面脚本每秒中才能跑300次,怀疑time、nc命令消耗了较多的时间,“改良”脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#!/bin/bash TIMEFORMAT="%E" i=0 host=127.0.0.1 port=${1-80} while :; do ((i++)) s=$(date +"%s.%N") exec 10<>/dev/tcp/$host/$port e=$(date +"%s.%N") exec 10>&- exec 10<&- [[ $( echo "($e -$s) > 0.9"|bc) -eq 1 ]] && echo -e "`date`\t$i\t$t" && break; if [[ $((i % 1000)) -eq 0 ]]; then echo -e "`date`\t$i" fi done |
这里省去了time、nc,但是出现了两次date命令;测试结果和上面脚本几乎一样
参考资料: http://www.cnblogs.com/chengmo/archive/2010/10/22/1858302.html