shell获取curl的返回结果_提高工作效率,Shell脚本技巧(二)

cc0c5beb78041011a628799648625a10.png

原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。

Shell批量处理

工作中,会一点点简单的Shell脚本编程,对于部分场景,能提高效率不少,比如这样一种需求:
业务同学需要去年一整年的订单量,所幸,线上已经有一个接口能够根据时间范围查询订单量,可惜的是,由于数据量过大,这个接口只能支持1天的时间范围。怎么办,为这个临时小需求再实现一个查询接口?
如果你会Shell脚本,就很简单了,将1年拆成365天,每一天,查询一下接口获取订单数量,最后再将数量汇总,即是1年的订单量。
下面主要是一些Shell脚本代码,但这里并不会介绍Shell的基础语法,没有Shell基础的同学,先看看这里一篇文章让你彻底掌握 shell 语言

nc模拟实现查询订单数量接口

这里为了方便,使用ncat命令模拟实现这个简单的http接口,接口实现的代码如下:

#!/bin/bash
while read line;do
    if [[ "$line" =~ ^GET && "$line" =~ countOrder ]];then
        #获取请求参数
        start_time=$(grep -oP "(?<=start_time=)[\dT:-]+" <<<$line);
        end_time=$(grep -oP "(?<=end_time=)[\dT:-]+" <<<$line);
        #生成随机的单量
        num=$(head /dev/urandom | tr -dc 0-9  | head -c 5);
        length=$(echo -n "$num"|wc -c)
        printf "%s,%s,%s\n" $start_time $end_time $num > /dev/tty;
        #返回http响应
        printf "HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: %d\r\n\r\n%s" $length $num
    fi;
done

接口接收到请求后,生成随机的订单量返回。
保存脚本为countOrderNum.sh,然后启动这个接口服务,如下:

# 启动接口服务
ncat -lk 8080 -e countOrderNum.sh
# curl调用接口
curl -s http://localhost:8080/countOrder?start_time=2019-01-01T00:00:00\&end_time=2019-01-02T00:00:00

效果如下:

301b840080f883d0a5a1d47d8f17d9dc.png

查询每日单量

接口已经有了,接下来实现查询每一天订单数量的脚本,如下:

#!/bin/bash
let begin=$(date -d "2019-01-01" +%s);
for i in {0..364}; do
    #计算本次循环的起始结束时间
    let start=$(($begin+$i*(24*60*60)));
    let end=$(($begin+($i+1)*(24*60*60)));
    #时间缀转日期字符串
    start_time=$(date --date="@$start" +"%Y-%m-%dT%H:%M:%S");
    end_time=$(date --date="@$end" +"%Y-%m-%dT%H:%M:%S");
    #调用接口获取数量
    count=$(curl -s http://localhost:8080/countOrder?start_time=$start_time\&end_time=$end_time);
    printf "%s\t%s\t%s\n" $start_time $end_time $count;
done

保存脚本为getDayCount.sh,脚本执行逻辑如下:

  1. 脚本以2019-01-01为起始时间,计算出相应的unix时间缀,保存在begin变量中。
  2. 接下来循环365次,其中i取值为0,1,2...364,计算每一天的start、end,其中24*60*60即1天的秒数,然后将start,end转换为日期字符串start_time,end_time,第一次循环start_time,end_time为2019-01-01T00:00:00,2019-01-02T00:00:00,第二次循环为2019-01-02T00:00:00,2019-01-03T00:00:00。
  3. 使用curl调用接口,并将start_time,end_time参数赋值。
  4. 打印出每日单量。

执行脚本,执行结果保存在data.txt中,效果如下:bash getDayCount.sh | tee data.txt

9466e2deb55ec3ce458b8424fd8986e5.png

汇总单量

然后将data.txt中的每日单量汇总后,即是一年总单量,使用awk命令很容易实现,将第3列累加起来即可。

$ cat data.txt|awk '{a += $3} END{print a}'
2480856

pv查看进度

365天,会执行365次接口查询,整体还是比较慢的,那么执行过程中,如何查看脚本执行的进度呢?
通过在执行脚本时,添加pv命令即可,如下:

$ bash getDayCount.sh | pv -l -s 365 > data.txt
264  0:00:37 [6.98 /s] [========================================>                ] 72% ETA 0:00:14

如上,用pv来观测进度是比较方便的,pv实现进度原理如下:

  1. 前面getDayCount.sh脚本每查询了一天就会输出一条日志,总共会输出365条日志
  2. pv的-l参数,表示统计从输入流读取到的行数,而-s 365参数,指定总共会读取到的行数,那么每当之前的getDayCount.sh完成1天的查询,就会输出一条记录给pv,pv就会将自己读到的行数加1,然后除以365来计算进度。
  3. pv显示中,最前面的264表示已处理数据量,这里即代表目前已查询了264天的数据,0:00:37代表脚本执行已花费的时间,6.98/s代表每秒处理查询6.98个,即处理速度。

xargs并发查询

上面的脚本,去查询每日单量,是顺序查的,查完第1天,再查第2天,一直到结束,整个查询下来,花费的时间也不少。
我们可以利用xargs来并发处理,脚本需要拆分为两个,如下:

  1. 生成1年的时间范围
#!/bin/bash
let begin=$(date -d "2019-01-01" +%s);
for i in {0..365}; do
    let start=$(($begin+$i*(24*60*60)));
    let end=$(($begin+($i+1)*(24*60*60)));
    start_time=$(date --date="@$start" +"%Y-%m-%dT%H:%M:%S");
    end_time=$(date --date="@$end" +"%Y-%m-%dT%H:%M:%S");
    printf "%s\t%s\n" $start_time $end_time;
done

保存为genDay.sh,与之前的逻辑类似,只是这个脚本单纯的生成时间范围,不调用接口。
2. 执行查询

#!/bin/bash
count=$(curl -s http://localhost:8080/countOrder?start_time=$1\&end_time=$2);
printf "%s\t%s\t%s\n" $1 $2 $count;

保存为queryDay.sh,脚本就是去调用接口获取单量,然后输出,单次调用效果如下:

$ bash queryDay.sh 2019-04-24T00:00:00 2019-04-25T00:00:00
2019-04-24T00:00:00     2019-04-25T00:00:00     12261
  1. 使用xargs并发3进程执行
$ ./genDay.sh |xargs -L1 -P3 ./queryDay.sh | pv -l -s 365 > data.txt
261  0:00:18 [14.6 /s] [================================================>                     ] 71% ETA 0:00:07

可以看到,由于使用了3个进程执行,处理速度明显变快了,之前处理到70%进度用了37s,这次只用了18s,之前处理qps是6.98/s,这次qps是14.6/s。
其中,xargs命令的作用是把输入流的数据,转化为后面脚本的参数,而-L1参数,表示每次读取1行数据,并将这一行数据按空白拆成参数传给queryDay.sh,-P3参数,表示使用3个进程来执行queryDay.sh。

总结

Shell脚本可以快速实现一些简单的小功能,简单学习了解一下,是非常值得的。

往期内容

提高工作效率,这些Linux命令可以帮到你(一)

这些实用的Linux技巧,看你知道几个!


f4f9b284b640f80c0785500273f4b820.png

长按关注【打码日记】

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用以下命令获取curl返回值: ``` curl -s -o /dev/null -w "%{http_code}" http://example.com ``` 其中,`-s`表示静默模式,不输出任何信息;`-o /dev/null`表示将curl的输出重定向到/dev/null,即不输出到终端;`-w "%{http_code}"`表示输出HTTP状态码。 如果需要在shell脚本获取curl返回值,可以使用以下语句: ``` status=$(curl -s -o /dev/null -w "%{http_code}" http://example.com) echo $status ``` 其中,`$()`表示执行命令并将结果赋值给变量`status`,然后使用`echo`命令输出变量值。 ### 回答2: curl是一个非常常用的网络工具,可以用来访问、下载文件和网络资源等。在使用curl时,我们有时候需要获取返回值来判断请求是否成功或者出错。而我们可以通过shell脚本获取curl返回值。 获取curl返回值可以通过curl命令的返回码来实现。curl命令成功的返回码是0,而其他的返回码则表示出现了错误。我们可以通过$?来获取上一个命令的返回值,也就是curl命令的返回值。 以下是一个示例脚本,使我们可以更好的理解如何获取curl返回值: #!/bin/bash result=$(curl -I -m 5 -o /dev/null -s -w %{http_code} http://example.com) if [ $result -eq 200 ]; then echo "访问成功" else echo "访问失败" fi 在这个脚本中,我们使用了curl的-I参数来获取HTTP头部信息,同时使用-m参数设置了最大请求时间为5秒钟。为了防止curl命令输出信息,我们使用了-o参数将结果输出到/dev/null中。最后,我们使用了-w参数来指定输出格式,即仅输出HTTP状态码。输出信息存储在$result变量中。 接下来,我们使用if语句来判断结果,如果返回值为200,则输出“访问成功”,否则输出“访问失败”。 总之,shell脚本可以很方便地获取curl返回值,并且可以根据返回值来执行相应的操作。这样可以大大提高我们在使用curl命令时的效率。 ### 回答3: 在shell脚本获取curl返回值可以使用$?变量。当curl执行成功时,$?变量的值为0,否则为1。我们可以在curl命令执行之后使用echo $?来输出返回值。 例如,我们可以使用以下代码来获取curl返回值: #!/bin/bash curl -I http://www.example.com/ if [ $? -eq 0 ]; then echo "curl执行成功" else echo "curl执行失败" fi 在上面的例子中,我们使用curl获取www.example.com的头信息。我们使用$?变量检查curl是否执行成功,并根据返回值输出相应的消息。如果curl成功执行,$?值为0,我们将输出“curl执行成功”。如果curl执行失败,$?值为1,我们将输出“curl执行失败”。 总结:在bash shell脚本中,使用$?变量来获取上一条命令的返回值,以便进一步处理命令的执行结果。在使用curl获取Web服务的响应时,我们可以使用$?变量来检查curl的执行是否成功。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值