【大数据】beeline 导出文件有特殊字符的问题解决

问题

近期在做大数据查询引擎导出文件的功能,使用了 hive 的 beeline 客户端。发现 beeline 导出的文件以及终端输出有许多特殊字符。

按照官方文档使用 beeline 导出命令:

/usr/bin/beeline --silent=true --showHeader=true --outputformat=csv2 -f query.hql </dev/null > /tmp/output.csv 2> /tmp/error.log

现象

在 vim 中显示为 ^M,在熟悉换行符的背景下,立即认出这就是 CR符号,也就是 \n

或者在excel文件头部,有很多 null,空格等符号。

分析

在做系统集成的时候,明显是不需要用 nohup的,因此没有采用文档中的写法,因为 nohup 一般直接在终端中使用;另外程序调用需要前台运行,等待结束后,获得exitCode,以及导出的文件和错误输出。

相关资料

另一位网友也遇到了这个问题,文章中分析了源码层面,可惜未给出合适的解决办法,但有启发。

过程

由前面的文档启发,观察 /bin/hive 脚本, 发现

if [[ "$SERVICE" =~ ^(hiveserver2|beeline|cli)$ ]] ; then
  # If process is backgrounded, don't change terminal settings
  if [[ ( ! $(ps -o stat= -p $$) =~ "+" ) && ! ( -p /dev/stdin ) && ( ! $(ps -o tty= -p $$) =~ "?" ) ]]; then
    export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Djline.terminal=jline.UnsupportedTerminal"
  fi
fi

在有使用过 Alibaba Cloud Toolkit 的背景下,立即发现这是一个 stty size 的问题。

解决

在程序调用的场景下,通过/bin/bash 进行调用,所以其实是以一个终端环境,终端就涉及到美化输出的问题

所以一定要设置终端类型为不支持终端,因此显式设置变量:

HADOOP_CLIENT_OPTS="-Djline.terminal=jline.UnsupportedTerminal"

ProcessBuilder _proc = new ProcessBuilder().inheritIO().command(arguments);
_proc.environment().put("HADOOP_CLIENT_OPTS","-Djline.terminal=jline.UnsupportedTerminal");
Process proc = _proc.start();

建议

一般导出的文件是UTF-8,对于Windows的用户来说,直接打开到Excel中文会乱码,最好添加上 BOM

一般添加的是EF BB BF


  1. https://hive.apache.org/docs/latest/hiveserver2-clients_30758725/#background-query-in-terminal-script ↩︎

  2. https://stefanxiepj.github.io/archives/241842c7.html ↩︎

  3. https://stackoverflow.com/questions/2223882/whats-the-difference-between-utf-8-and-utf-8-with-bom ↩︎

posted @   一杯半盏  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示