这里 - 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,但似乎我可以处理它。
答案 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
我把它留作练习来研究如何正确地缩进这里文件的正文。