hive 命令行的使用
hive –help 获取帮助信息
[root@master data]# hive --hlep --service cli
Unrecognized option: --hlep
usage: hive
-d,--define Variable subsitution to apply to hive
commands. e.g. -d A=B or --define A=B
--database Specify the database to use
-e SQL from command line
-f SQL from files
-H,--help Print help information
--hiveconf Use value for given property
--hivevar Variable subsitution to apply to hive
commands. e.g. --hivevar A=B
-i Initialization SQL file
-S,--silent Silent mode in interactive shell
-v,--verbose Verbose mode (echo executed SQL to the
console)
hive -e 使用方法
hive -e 'create table hive_cli2(id int)' #h-sql 语句,需要使用'' 括起来
hive -e 'desc hive_cli2'
OK
id int
hive -e 'show tables'
hive_cli2
hive -f 的使用方法,将h-sql 语句放在文件里面,然后使用hive -f H-SQL_FILENAME
# hive脚本中的注释在行首使用 "--",但是在cli 中不支持这样的注释。
[root@master ~]# cat hive_file.txt
-- hive 脚本文件的注释,测试hive -f 这个参数
CREATE TABLE userinfo
(
id int,
name string,
age string
)
row format delimited fields terminated by '\t'
lines terminated by '\n';
show tables
hive -f hive_file.txt # 使用这种方式可以使hive一次执行多条命令
输出:
userinfo
hive -i 和 hive -f 用法相同,两者的区别
hive -i filename 在进入hive终端的时候,执行filename 这个文件,这个文件存储的内容一般是一些配置信息,如设置系统属性,增加hadoop的分布式内存,进行自定义的hive扩展的jar包
hive -f filename 执行完文件中的h-sql 命令后不进入hive cli 终端
hive启动的时候,默认情况下会找bash $HOME/.hiverc 这个文件,执行这个文件的一些配置,等价于hive -i ~/.hiverc
${HOME}/.hivehistory 这个文件存储了hive cli 中执行命令的历史记录
hive cli 终端中可以使用tab 键补齐命令,使用tab键需要注意:如果某些行是以tab键开头的话,就会产生一个常见的令人困惑的错误,用户这时会看到一个"是否显示所有可能的情况"的提示,而且输入流后面的字符会被认为是对这个提示的回复,也因此会导致命令执行失败
hive -S 进入hive cli 终端后,执行命令使用静默模式,过滤掉一些日志信息(一些提示信息,如:OK,用时等信息,但是错误信息是不会过滤掉的),只输出结果信息,如果是创建/删除表,完成后没有任何信息返回
hive (default)> !pwd; # hive cli 终端可以执行shell命令,前面加一个""
/root
hive cli 终端还可以执行hdfs 中的dfs命令,需要将hdfs命令去掉,直接运行dfs,但是注意不支持输入hadoop fs -ls /。这种使用hadoop 命令的方式实际上比在base中执行要高效,因为在base中执行hadoop命令,每次都需要启动一个新的JVM实例,而在hive中会在同一个JVM进程中执行这些命令
hive (default)> dfs -ls /; # 等价于bash 中 hdfs dfs -ls / 或者 bash 中 hadoop fs -ls /
Found 4 items
-rw-r--r-- 3 root supergroup 114 2018-01-25 07:59 /b.txt
drwx-wx-wx - root supergroup 0 2018-01-26 03:34 /data
drwx-wx-wx - root supergroup 0 2018-01-24 09:24 /tmp
drwxr-xr-x - root supergroup 0 2018-01-24 09:21 /user
#获得dfs 命令的帮助信息
dfs -help;
hive -d a=b #设置 k=v 在hive cli 中设置变量替换
hive> set a;
a=b
hive> set hivevar:a
a=b
hive --defin key=value 实际上和 hive cli --hivevar key=value 是等价的。二者都可以让用户在命令行定义用户自定义变量以便在hive脚本中引用,来满足不同情况的执行。注意这个功能只有在hive 0.8 版本和之后的版本才支持
hive 中变量和属性命名空间:
命名空间 使用权限 描述
hivevar 可读写 hive 0.8及后续版本支持,用户自定义变量
hiveconf 可读写 hive 相关配置属性
system 可读写 java 定义的配置属性
env 只读 Shell 环境,定义的环境变量
hive 变量内部是以java 字符串的方式存储的。用户可以在查询中引用变量。hive会优先使用变量值替换掉查询的变量引用,然后才会将查询语句提交给查询处理器
hive cli set 命令,会打印命名空间hivevar,hiveconf,system和env中所有的变量。使用-v 标记,则还会打印Hadoop 中定义的属性,列如HDFS 和MapReduce的属性
[root@master ~]# hive --define filed=username
hive> set filed;
filed=username
hive> set hivevar:filed;
hivevar:filed=username
hive> set filed=user_name;
hive> set filed;
filed=user_name
hive> set hivevar:filed;
hivevar:filed=username
hive> create table userinfo(id int,${filed} string);
OK
Time taken: 0.927 seconds
hive> create table userinfo1(id int,${hivevar:filed} string);
OK
Time taken: 0.431 seconds
hive> desc userinfo;
OK
id int
username string
Time taken: 0.115 seconds, Fetched: 2 row(s)
hive> desc userinfo1;
OK
id int
username string
Time taken: 0.044 seconds, Fetched: 2 row(s)
hive>
从上面的代码可以看出,在shell终端使用hive命令,然后带上--define 参数定义的变量和在hive cli 终端中使用set hivevarvariable_name=value 定义的变量等价。但是在hive cli 终端,修改以存在变量的值必须带上hivevar: 前缀,否则不生效,获取以存在变量的值不需要带hivevar: 这个前缀。同样的在hive cli 终端定义变量,必须带上hivevar: 这个前缀
下面两个命令都是获取hivevar 这个命名空间中,foo 这个变量的值
set foo; # 如果之前没有定义过这个变量(没有运行这条命令 set hivevar:foo),默认是获取hiveconf 这个命名空间的
set hivevar:foo
set hivevar:foo=test
这个命令的意思是将hivevar 命名空间中foo的值设置为test,如果这个变量以存在就是修改变量的值,如果这个变量不存在就创建这个变量并赋值test
set foo=test1
这条命令等同于 set hiveconf:foo=test1
set key=value 这个是设置hive的配置不是设置hive变量,属于hiveconf 命名空间,等价于hive-site.xml 文件中的配置,但是离开hive终端后设置失效
详情见下面的实例:
hive> set var_name;
var_name=test5
hive> set hiveconf:var_name;
hiveconf:var_name=test5
hive> set hive.exec.scratchdir=/tmp/mydir;
#等价于 ${HIVE_HOME}/conf/hive-site.xml 这个文件中添加下面4行
<configuration>
<property>
<name>hive.exec.scratchdirname>
<value>/tmp/mydirvalue>
<description>Scratch space for Hive jobsdescription>
property>
configuration>
[root@master ~]# hive --hiveconf y=5
Logging initialized using configuration in jar:file:/data/tools/hive/lib/hive-common-1.2.2.jar!/hive-log4j.properties
hive> set y;
y=5
hive> select * from word_count where count=${hiveconf:y}; #hiveconf: 这个前缀不能省
OK
by 5
day 5
life 5
what 5
when 5
Time taken: 0.187 seconds, Fetched: 5 row(s)
--conf 等同于在hive cli 终端使用set 设置属性一样
hive> set y;
y is undefined
hive> set y=5;
hive> select * from word_count where count=${hiveconf:y};
OK
by 5
day 5
life 5
what 5
when 5
Time taken: 0.928 seconds, Fetched: 5 row(s)
可以将env 命名空间中的环境变量传递到hive cli 中
如果--hiveconf 后面接一个文件名或者目录,貌似不起作用,这个有待研究,下面看一个实例:
[root@master ~]# cat /tmp/hive-site.xml
<configuration>
<property>
<name>hive.exec.compress.outputname>
<value>truevalue>
property>
<property>
<name>map.input.filename>
<value>/b.txtvalue>
property>
configuration>
启动hive
[root@master ~]# hive --hiveconf /tmp/hive-site.xml
hive> set hiveconf:hive.exec.compress.output; # 这个属性默认值是false,上面的配置文件设置的是true,可是没有生效
hiveconf:hive.exec.compress.output=false
hive> set map.input.file; # 这个属性没有默认值,上面的配置文件设置了,可以这里同样没有生效
map.input.file is undefined
[root@master ~]# export a=10 # 注意这里需要使用export 将a变成系统环境变量,如果没有export这个关键字,a这个变量是无法在hive中引用的
[root@master ~]# echo $a
10
hive> set env:a;
env:a=10
hive> select * from word_count where count = ${env:a};
OK
a 10
we 10
Time taken: 0.501 seconds, Fetched: 2 row(s)
另一种实现方式使用 hive -e 这样就不需要使用export关键字
COUNT=5 hive -e 'select * from word_count where count=${env:COUNT}';
#输出:
by 5
day 5
life 5
what 5
when 5
# 验证COUNT 这个变量在hive中引用是否正确
hive -e 'select * from word_count where count=5';
#输出结果:
by 5
day 5
life 5
what 5
when 5
# 结果一样
当用户不能完整记清楚某个属性名是,可以使用下面的方法来获得
[root@master ~]# hive -S -e 'set' | grep warehouse
hive.metastore.warehouse.dir=/user/hive/warehouse
hive.warehouse.subdir.inherit.perms=true
查询表的时候,显示字段名称
hive (default)> set hive.cli.print.header=true;
hive (default)> select * from word_count limit 3;
OK
word_count.word word_count.count
81
a 10
about 2
Time taken: 0.396 seconds, Fetched: 3 row(s)