Bash脚本中echo语句无输出问题:CSV导入SQL表场景
问题:Bash脚本SQL插入成功,但验证echo无预期输出
我编写了一个从CSV文件自动向两个SQL表插入数据的Bash脚本,数据插入功能正常,但插入后的验证echo语句(例如Inserted into teams, Brazil)无法输出预期内容。
原脚本代码:
echo $($PSQL "TRUNCATE TABLE games, teams") cat games.csv | while IFS=',' read YEAR ROUND WINNER OPPONENT WINNER_G OPPONENT_G do TEAMS=$($PSQL "SELECT name FROM teams WHERE name='$WINNER'") if [[ $WINNER != "winner" ]] then if [[ -z $TEAMS ]] then INSERT_TEAM=$($PSQL "INSERT INTO teams(name) VALUES('$WINNER')") if [[ INSERT_TEAM == "INSERT 0 1" ]] then echo Inserted into teams, $WINNER fi fi fi TEAMS2=$($PSQL "SELECT name FROM teams WHERE name='$OPPONENT'") if [[ $OPPONENT != "opponent" ]] then if [[ -z $TEAMS2 ]] then INSERT_TEAM2=$($PSQL "INSERT INTO teams(name) VALUES('$OPPONENT')") if [[ INSERT_TEAM2 == "INSERT 0 1" ]] then echo Inserted into teams, $OPPONENT fi fi fi done
问题原因及解决方案
1. psql查询输出包含冗余内容,导致空值判断失败
默认psql执行SELECT查询时,会输出表头、结果行、行数统计和换行符,比如查询存在的球队时输出类似:
name ------ Brazil (1 row)
这意味着TEAMS变量并非空值,而是包含这些冗余文本,[[ -z $TEAMS ]]的判断永远为假,不会触发后续的插入验证echo。
修复:给psql加上-t(仅输出结果行,去掉表头和行数)和-A(无对齐空格)参数,确保变量只获取纯数据:
TEAMS=$($PSQL -t -A "SELECT name FROM teams WHERE name='$WINNER'") TEAMS2=$($PSQL -t -A "SELECT name FROM teams WHERE name='$OPPONENT'")
2. INSERT语句输出判断不可靠
不同PostgreSQL版本或psql配置下,插入成功的输出可能不是INSERT 0 1,比如部分环境会输出INSERT 1 0,或者因参数配置改变输出格式,导致匹配失败。
修复:改用命令退出状态码判断插入是否成功,这是更可靠的方式:
# 替换原插入判断逻辑 if [[ $WINNER != "winner" ]] then TEAMS=$($PSQL -t -A "SELECT name FROM teams WHERE name='$WINNER'") if [[ -z $TEAMS ]] then # 屏蔽psql输出,仅判断退出状态 if $PSQL "INSERT INTO teams(name) VALUES('$WINNER')" > /dev/null 2>&1 then echo Inserted into teams, $WINNER fi fi fi
> /dev/null 2>&1用来屏蔽psql的正常输出和错误信息,if直接判断命令是否执行成功(退出码为0表示成功)。
3. 可选优化:避免管道子shell问题
原脚本中cat games.csv | while ...的结构会让while循环运行在子shell中,虽然不影响当前echo输出,但如果后续需要在循环外使用变量,会出现问题。可以改为直接读取文件:
while IFS=',' read YEAR ROUND WINNER OPPONENT WINNER_G OPPONENT_G do # 原有逻辑(已修复的版本) done < games.csv
内容的提问来源于stack exchange,提问作者Abdullateef Olawale
相关产品推荐
相关产品推荐

