impala-shell 将奇数控制字符插入到对非交互式查询的响应中

impala-shell inserts odd control characters into the response to a non-interactive query

我在 impala 中运行查询以检查 table 中是否满足条件并将行数存储在 bash 变量中:

UC=$(impala-shell -r -q "select count(1) from table where condition=1" -d $DB -i $HOST -B)

UC 现在保存条件为 1 的行计数,在这种情况下,没有行满足此条件:

echo $UC
 0

我检查 UC 值的比较失败,因为它前面有奇怪的控制字符。

if [ "$UC" == "0" ]; then echo 1; else echo 0; fi
0

echo $UC | hexdump
0000000 5b1b 313f 3330 6834 3020 000a
000000b

当我尝试从输入中删除非数字时,我得到了奇怪的输出

echo $UC | sed 's/[^0-9]*//g'
10340

这里发生了什么?如何设置结果格式以进行简单比较?

ESC[?1034h 是一个 xterm 控制序列,意思是 "Interpret meta key, sets eighth bit." (一个有用的 xterm 控制序列列表是 here。)所以大概 impala-shell 注意到您有一个 xterm 兼容的终端,并且正在尝试初始化它以供交互使用,即使 -q 命令行选项使它变得毫无意义。

您可以通过调用 impala-shell 并将 TERM 环境变量设置为 ansi 来避免该问题,这将阻止基于 terminfo 的程序发出 smm控制序列:

UC=$(TERM=ansi impala-shell -r -q "select count(1) from table where condition=1" \
                            -d $DB -i $HOST -B)

您还可以通过重定向 stdin:

说服 impala-shell 互动是不必要的
UC=$(impala-shell </dev/null -r -q "select count(1) from table where condition=1" \
                             -d $DB -i $HOST -B)

无论如何,向 impala-shell 的作者提出功能请求似乎是合理的。我认为问题出现在 impala_shell.py (self.readline = __import__('readline')) 的第 142 行; import readline 具有初始化底层 readline 库的副作用,然后有效地执行 tput smm;如果$TERM表示smm存在,则发送。如果要使用 readline 库,初始化它没有错,但在非交互式 shell 的情况下,您将不会使用它。因此,一种解决方案是在导入 readline 之前检查交互性(如果导入失败,已经有回退)。另一种选择可能是延迟导入 readline(并因此对其进行初始化),直到实际需要它为止。