【问题标题】:Save curl response AND -w to variables将 curl 响应和 -w 保存到变量
【发布时间】:2021-03-31 08:29:22
【问题描述】:

我正在使用以下命令来卷曲一个 url,并显示 --write-out 选项提供的 response_codetime_total

curl -o /dev/null -sL $@ -w "$(printf %-100.100s $@) %{response_code}\t%{time_total}\n"
# https://example.com/?p=5                                200            0.084437

由于某些页面显示 cms based 404,我想检查页面内容中的特定字符串,并在输出中显示contains: true/false

https://example.com/?p=4                  No               200           0.084437
https://example.com/?p=5                  Yes              200           0.081241

所以我想真正的问题是,如何让-w 显示他的输出,同时将响应正文保存到变量中?

根据this 的回答,我目前正在使用这种解决方法:

# <body>\n<code>#<time>
c=$(curl -o - -s -L ${1} -w "%{response_code}#%{time_total}")

# Body
cb=$(sed '$ d' <<< "$c")

# Info
ci=$(tail -n1 <<< "$c")
IFS='#' read -r -a cs <<< "$ci"

# CMS-404
ul=<regex magic>
[[ $ul != ${2} ]] && pe="CMS-404" || pe=""

# Print result
printf "$(printf %-100.100s ${1})\t${pe}\t\t${cs[0]}\t${cs[1]}\n"

捕获完整的输出,获取最后行,巫婆包含-w信息,并使用sed获取剩余内容,即正文。

由于我希望-w 输出(可选)为多行,因此我正在寻找一种更可靠的方法来执行此操作。


链接的问题/答案

附加信息

Version
curl 7.64.1
bash 3.2.57(1)-release
OS Mac OS X 10.15.7

编辑,基于@Philippe's answer,这似乎可行,但是,ci="${c#*$'\1'}" 非常慢,因为我使用此功能处理 1000 多个网址,我希望有一个“更快”的解决方案。

我已使用以下脚本对此进行了简化测试;

#!/bin/bash

get() {

    echo "---> ${1}"

    # Request
    c=$(curl -o - -s -L ${1} -w $'\1'"%{response_code}#%{time_total}")

    # Body
    cb="${c%$'\1'*}"
    time_after_body=$(date +%s%N)

    ci="${c#*$'\1'}"
    time_after_info=$(date +%s%N)

    time_diff="$((time_after_info - time_after_body))"
    echo "TimeDiff: ${time_diff}ms"
    echo "CurlInfo: ${ci}"
}

get "https://stackoverflow.com/questions/65395089/save-curl-response-and-w-to-variables"
 ✗ ./small_so.sh
---> https://stackoverflow.com/questions/65395089/save-curl-response-and-w-to-variables
TimeDiff: 9886412000ms
CurlInfo: 200#0.469687

【问题讨论】:

    标签: bash curl


    【解决方案1】:

    你能用$'\1'这样的标记吗?

    #!/usr/bin/env bash
      
    c=$(curl -o - -s -L ${1} -w $'\1'"%{response_code}#%{time_total}")
    
    cb="${c%$'\1'*}"
    
    ci="${c#*$'\1'}"
    
    declare -p cb ci
    
    # Calling method : ./test.sh "https://example.com/?p=5"
    

    我刚刚在macos上测试过:

    ~/$ /bin/bash --version
    GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20)
    Copyright (C) 2007 Free Software Foundation, Inc.
    
    ~/$ /bin/bash test.sh "https://example.com/?p=5"
    declare -- cb="<!doctype html>
    ...
    "
    declare -- ci="200#0.693779"
    

    【讨论】:

    • 不幸的是代码挂在ci="${c#*$'\1'}",以前从未使用过这些标记。有任何 bash 版本限制吗?感谢您的尝试!
    • 更新了我的答案。 bash 3.2.57 应该支持我脚本中的语法。你能分享你使用的命令吗?
    • 如果更新了我的问题。让它与你的例子一起工作。似乎是一个可靠的解决方案,非常感谢。但是,请您看一下 OP 中的示例脚本,我是ci="${c#*$'\1'}" 似乎需要相当长的时间。
    • 确实,我这边也很慢(18 秒)。你能试试ci="${c##*$'\1'}" 和双#
    • 哇,那是相当不同的哈哈。单个请求大约需要 0.8 秒。你介意解释一下为什么这会产生如此巨大的影响吗?
    猜你喜欢
    • 2020-05-03
    • 2013-04-26
    • 2021-07-13
    • 2016-12-03
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 2015-04-27
    相关资源
    最近更新 更多