bash:从重定向的输入命令返回代码

时间:2015-07-28 14:12:13

标签: mysql bash io-redirection return-code

我有一个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来保存查询结果。我希望不要经常阅读和写入磁盘,但我的截止日期很快就要到了。

1 个答案:

答案 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退出并显示失败代码,即使它会成功将该行拆分为变量field2while。这使得不必尝试将错误指示与while循环内的正常数据区分开来,尽管在git diff <BRANCH-NAME> --diff-filter=D --name-only --exit-code | xargs git checkout <BRANCH-NAME> 循环后仍需要明确指示测试。