如何解析/ bin / sh的HTTP头?

时间:2016-10-02 17:14:35

标签: linux bash sh embedded-linux

这里 - How to parse HTTP headers using Bash?有一个非常优雅的解决方案,可以在没有awk的情况下解析bash:

shopt -s extglob # Required to trim whitespace; see below

while IFS=':' read key value; do
    # trim whitespace in "value"
    value=${value##+([[:space:]])}; value=${value%%+([[:space:]])}

    case "$key" in
       Server) SERVER="$value"
               ;;
       Content-Type) CT="$value"
               ;;
       HTTP*) read PROTO STATUS MSG <<< "$key{$value:+:$value}"
               ;;
    esac
done < <(curl -sI http://www.google.com)
echo $STATUS
echo $SERVER
echo $CT

但如何将其转换为纯粹的sh?

我还打算使用wget而不是curl,但似乎我可以处理它。

3 个答案:

答案 0 :(得分:0)

如果您没有extglob,则可以使用

修剪空白
set -- $value
value=$*

这将使用壁球场内部空白,但在这种情况下这似乎无害。它还将执行通配符扩展,这是一个更麻烦的问题;如果您可以使用它,set -f会解决这个问题。

然而,也许最简单的解决方案是管道到一个简单的Awk脚本来分配变量,所以你可以eval

eval $(curl -sI http://www.google.com |
    awk -v q="'" '{ gsub(/\r/, ""); gsub(q, q "\"" q "\"" q); }
        /HTTP\// { print "PROTO=" q $1 q; 
            print "STATUS=" q $2 q; print "MSG=" q $3 q; next }
        /^Server: / { $1="SERVER=" q; $NF = $NF q; sub(q " ", q); print; next; }
        /^Content-Type: / { $1="CT=" q; $NF = $NF q; sub(q " ", q); print; next; }')

单引号应该足以确保eval是安全的,但我确信空白处理可能更强大。

答案 1 :(得分:0)

使用heirloom-sh进行测试。它应该适用于您找到的任何bourne shell:

(curl -I -s http://www.example.com;echo)| (
read HTTP_VAR_PROTO HTTP_VAR_STATUS HTTP_VAR_MSG
while IFS=': ' read -r key value; do
    case "$key" in
       Server) HTTP_VAR_SERVER="$value"
               ;;
       Content-Type) HTTP_VAR_CONTENT_TYPE="$value"
               ;;
       '')
        set #remove "set" and put your script here
        ;;
    esac
done
)

我已经使用HTTP_VAR_为set vars添加前缀,以避免让HTTP响应覆盖环境中的重要位。很遗憾你必须将你的脚本放在 case里面,但是没有办法(不使用外部程序或eval输入)来获取read按照你想要的方式在沼泽标准的伯恩身上工作。

答案 2 :(得分:0)

您可以使用read和here文档修剪空白。使用命名管道来模拟&#34;过程替代。 (实际上,在某些操作系统上,可以使用命名管道实现进程替换。)

mkfifo headers
curl -sI http://www.google.com > headers &

{
  # This line is guaranteed to be first, before any headers.
  # Read it separately.
  read -r PROTO STATUS MSG
  while IFS=':' read -r key value; do
      # trim whitespace in "value"
      read -r value <<EOF
$value
EOF

      case $key in
         Server) SERVER="$value"
                 ;;
         Content-Type) CT="$value"
                 ;;
      esac
  done
} < headers
rm headers

我把它留作练习来研究如何正确地缩进这里文件的正文。