我有一个bash脚本,我正在使用它来循环并处理来自SQL查询的结果。
while read field1 field2 field3 field4
do
{...something here...}
done < <(mysql -h $HOST -u $USER -p"$PASS" $DB << EOF
{...multi-line select query here...}
EOF)
我不知道如何解决的问题是如何重构这个以便我可以获取返回代码,错误输出并在出现错误时跳过循环查询数据库?
编辑:
我尝试使用带有以下内容的命名管道。
mkfifo /tmp/mypipe
mysql -h $HOST -u $USER -p"$PASS" $DB << EOF >> /tmp/mypipe
{...multi-line select query here...}
EOF
echo $?
{...loop here...}
这似乎不起作用,因为mysql命令位于等待继续之前读取管道。所以除非我有东西读取管道,否则mysql不会退出以获得返回代码。
我已经尝试将查询结果首先存储到变量中,其中包含以下内容。
DATADUMP=$(mysql -h $HOST -u $USER -p"$PASS" $DB -e \
'select stuff from place \
join table 1 on record ..... \
')
我遇到的问题是读取循环只会读取前四个&#34;单词&#34;来自DATADUMP变量并忽略其余部分。
此时,除非有人带回一个好主意,否则我将使用临时文件mktemp来保存查询结果。我希望不要经常阅读和写入磁盘,但我的截止日期很快就要到了。
答案 0 :(得分:0)
除了在处理mysql
命令之前捕获while
命令的整个输出之外,没有其他方便的方法。如果您认为它不是千兆字节的数据,或者是临时文件,您可以将其捕获到变量中。这是保证在发生错误时不会处理部分结果的唯一方法。
如果您知道所有错误都产生空输出,那么它将相当简单,因为got_data=0
while read field1 field2; do
got_data=1
# ...
done < <( mysql ... || printf "%s %d" "ERROR" $?) <<EOF
# ...
EOF
)
if ((!got_data)); then
if [[ $field1 == "ERROR" ]]; then
# error code is in $field2
else
# query returned no result
fi
循环根本不会执行。您将无法区分错误和空搜索,但您可以通过生成错误指示来解决此问题:
mysql
然而,前提可能是错误的。特别是,查询返回中间的网络故障可能会产生一些输出和错误指示。在这种情况下,上面的代码将处理部分返回。
如果您实际上不介意处理部分结果,只要最终检测到错误,那么您可以使用上述代码的简单变体。该代码保证ERROR
的不成功退出最终将产生以mysql
标记开头的行。 (如果网络传输中断,我不知道printf
是否保证尾随换行的输出。你需要玩一些游戏以保证ERROR 3
输出的错误行总是出现在单独行。)
上面有一个小技巧:错误行(例如printf
)与read
一起输出,没有尾随换行符。缺少尾随换行符会导致field1
退出并显示失败代码,即使它会成功将该行拆分为变量field2
和while
。这使得不必尝试将错误指示与while
循环内的正常数据区分开来,尽管在git diff <BRANCH-NAME> --diff-filter=D --name-only --exit-code | xargs git checkout <BRANCH-NAME>
循环后仍需要明确指示测试。