Bash脚本变量输出异常:字数统计变量嵌入URL问题排查
Bash脚本字数统计输出异常排查(\r字符干扰问题)
问题背景
刚接触Bash,写了个脚本读取URL列表文件,提取每个URL的HTTP状态码、响应编码和页面字数统计。状态码和编码提取都正常,但字数统计的输出总是异常:单独执行curl ... | wc -w能得到正确数字,但把结果存到变量后输出时,数字会嵌入到URL字符串里,只有个别URL显示正常。怀疑是提取编码时带了\r(回车符)导致的问题。
相关信息
脚本代码
while IFS= read -r url; do # 获取HTTP状态码 status=$(curl -s -o /dev/null -w "%{http_code}" "$url") # 提取响应编码 charset=$(curl -s -I "$url" | grep -i "content-type" | grep -oE "charset=[^;]*" | cut -d= -f2) # 统计页面字数 word_count=$(curl -s "$url" | wc -w) # 输出结果 echo "URL: $url | 状态码: $status | 编码: $charset | 字数: $word_count" done < urls.txt
异常输出示例
URL: https://example.com | 状态码: 200 | 编码: UTF-8 | 字数: 1234
URL: | 状态码: 200 | 编码: GBK | 字数: 567https://test.com
bash -x调试日志片段
+ IFS= + read -r url + url='https://test.com' + curl -s -o /dev/null -w %{http_code} https://test.com + status=200 + curl -s -I https://test.com + grep -i content-type + grep -oE charset=[^;]* + cut -d= -f2 + charset='GBK\r' + curl -s https://test.com + wc -w + word_count=567 + echo 'URL: https://test.com | 状态码: 200 | 编码: GBK\r | 字数: 567'
问题原因与解决办法
核心原因
从调试日志能明确看到:charset变量末尾带有回车符(\r)。当执行echo输出时,\r会把光标移到当前行的开头位置,导致后面的“字数: 567”内容覆盖了前面的URL部分,最终出现数字嵌入URL的异常显示。
解决方法
在提取charset后,立即移除末尾的\r字符,三种常用实现方式:
- 使用
tr命令删除回车符:
charset=$(curl -s -I "$url" | grep -i "content-type" | grep -oE "charset=[^;]*" | cut -d= -f2 | tr -d '\r')
- 使用
sed替换掉行尾的回车符:
charset=$(curl -s -I "$url" | grep -i "content-type" | grep -oE "charset=[^;]*" | cut -d= -f2 | sed 's/\r$//')
- 利用Bash内置的参数展开功能:
# 提取charset之后执行 charset=${charset%$'\r'}
效率优化建议
当前脚本每个URL要发起3次curl请求,效率较低,可以优化为1-2次请求:
while IFS= read -r url; do # 创建临时文件保存页面内容 temp_page=$(mktemp) # 一次请求同时获取状态码和页面内容 status=$(curl -s -o "$temp_page" -w "%{http_code}" "$url") # 提取编码并清理回车符 charset=$(curl -s -I "$url" | grep -i "content-type" | grep -oE "charset=[^;]*" | cut -d= -f2 | tr -d '\r') # 统计字数 word_count=$(wc -w < "$temp_page") # 输出结果 echo "URL: $url | 状态码: $status | 编码: $charset | 字数: $word_count" # 删除临时文件 rm "$temp_page" done < urls.txt
内容的提问来源于stack exchange,提问作者Gwayns
相关产品推荐
相关产品推荐

