为什么Vim编写的Bash脚本运行效果与终端直接执行不一致?
问题原因
- 端口文件存在Windows格式换行符:你使用的
common_ports.txt如果是在Windows系统下创建或传输的,行尾会携带\r回车符,读取到$line变量后拼接URL时,\r会触发终端光标回到行首的逻辑,后续输出的内容会直接覆盖前面的Content-Length内容,最终只会显示最后输出的Date字段。你看到输出末尾的9-8残段就是被覆盖的端口号内容。 - 变量引用未加双引号丢失换行符:
echo $response没有给变量包裹双引号,Bash会自动将变量内的所有换行、制表符等空白符替换为空格,把原本多行的响应头压成单行,导致grep匹配逻辑和你手动执行时的多行匹配结果不一致。
修复方案
- 先转换端口文件的换行格式,执行命令:
dos2unix common_ports.txt,如果没有dos2unix工具,也可以直接在read逻辑中过滤\r符。 - 所有变量引用都加上双引号保留原始格式,同时给curl增加超时参数避免请求卡住,优化后的脚本如下:
#!/bin/bash file="./common_ports.txt" while IFS=$'\r\n' read -r line || [[ -n $line ]] do # 跳过空行 [[ -z "$line" ]] && continue # curl加-m 2设置2秒超时,-sS关闭进度条只输出错误 len=$(curl -sS -m 2 -Is "http://10.10.182.210:8000/attack?port=$line" | grep "Content-Length:") echo "端口$line: $len" done < "$file"
也可以直接省略中间变量response,将curl和grep通过管道直接连接,进一步降低变量处理出错的概率。
内容的提问来源于stack exchange,提问作者Elkhan
相关产品推荐
相关产品推荐

