Shell脚本中while循环未执行问题及CSV转HTML需求
嘿,你的while循环直接跳过不执行,大概率是这几个常见坑导致的,咱们一步步排查解决:
1. 先确认生成的CSV文件真的有内容
最基础的问题:你用SQL生成的$logFile是不是空的?
在脚本的while循环前加一段检查代码,先把这个可能性排除:
# 检查CSV文件是否存在且非空 if [ ! -s "$logFile" ]; then echo "Error: CSV文件 $logFile 为空或者不存在!" exit 1 fi
如果运行脚本时输出这个错误,那问题根源在SQLPlus的查询环节——要么你的SQL没返回数据,要么输出重定向的写法错了,导致文件根本没被写入内容。
2. 修正SQLPlus的输出重定向写法
看你给出的代码片段,SQLPlus部分的输出重定向可能没写对。正确的写法应该把> "$logFile"放在Here Document的后面,这样SQLPlus的查询结果才会写入到目标CSV文件里,而不是输出到终端:
sqlplus -s MODA_WORK_REPO/*****#@wcdsa << EOSQL > "$logFile" SET COLSEP , SET PAGESIZE 700 SET LINESIZE 200 SET FEEDBACK OFF SET HEADING ON SET TERMOUT OFF # 关闭终端输出,只保留查询结果 SET ECHO OFF # 这里替换成你的实际查询语句 SELECT column1, column2, column3 FROM your_table; EXIT; # 确保SQLPlus正常退出 EOSQL
加上SET TERMOUT OFF可以避免SQLPlus输出连接提示、版本信息这类多余内容,保证CSV文件里只有纯查询结果;EXIT;能确保SQLPlus执行完查询后正常退出,避免残留进程。
3. 修正While循环的读取写法
假设CSV文件已经有内容,但循环还是没执行,那可能是循环的读取方式有问题。比如用cat | while read的管道写法,有时候会因为子shell的问题导致异常,但更常见的是读取逻辑没匹配CSV格式。推荐用更可靠的重定向写法:
# 生成HTML头部 echo "<html><body><table border='1'>" > output.html # 读取CSV文件,按逗号分隔列 while IFS=, read -r col1 col2 col3 # 根据你的实际列数调整变量数量 do # 把每行CSV转成HTML表格行 echo "<tr><td>$col1</td><td>$col2</td><td>$col3</td></tr>" >> output.html done < "$logFile" # 生成HTML尾部 echo "</table></body></html>" >> output.html
这里IFS=,指定了CSV的分隔符是逗号,-r参数避免读取时解析转义字符,< "$logFile"直接把文件作为循环的输入源,比管道写法更稳定。
快速排查小技巧
在脚本的while循环前加一行cat "$logFile",运行脚本时看看输出的内容是不是你预期的纯CSV格式。如果输出为空,就去调试SQL查询;如果有内容但循环没执行,就检查循环的语法是否正确。
内容的提问来源于stack exchange,提问作者Amit

