You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 17:07:17