相关文章推荐
单身的斑马  ·  【超详细】springboot + ...·  1 月前    · 
曾经爱过的刺猬  ·  c# - IsEnabled button ...·  1 年前    · 
纯真的石榴  ·  jstl maven依赖图形化-掘金·  1 年前    · 
悲伤的茄子  ·  oracle ...·  1 年前    · 

jar包的CSDN的下载地址

jar包名 说明
jline-3.6.2.jar 提供命令行开发需要的类和方法(核心jar包)

因为在windows上需要用到系统的dll文件(动态链接库),所以还需要下面五个jar包:

jar包名 说明
jansi-1.17.jar Jansi是一个用于生成和解释ANSI转义序列的java库
jna-4.2.2.jar Java本机访问
jsr305-3.0.2.jar Findbugs的JSR305注释
juniversalchardet-1.0.3.jar Java编码检测器库
sshd-core-1.4.0.jar

3.搭建一个最基础的框架

(1)计算机上的虚拟终端

Terminal terminal = TerminalBuilder.builder().system(true).build();
代码说明
TerminalBuilderTerminalBuilder类,创建终端的生成器类
.builder()返回new TerminalBuilder()
.system(true)给TerminalBuilder类中的system赋值并返回TerminalBuilder类
.build()调用TerminalBuilder类中的build()方法获取Terminal 并返回Terminal

(2)通过输入从控制台读取行

LineReader lineReader = LineReaderBuilder.builder().terminal(terminal).build();
代码说明
LineReaderBuilderLineReaderBuilder 类
.builder()返回new LineReaderBuilder ()
.terminal(terminal)给LineReaderBuilder 类中的terminal赋值并返回LineReaderBuilder 类
.build()返回LineReader

(3)原样输出输入的内容的demo

public static void main(String[] args) {
	try {
		Terminal terminal = TerminalBuilder.builder().system(true).build();
		LineReader lineReader = LineReaderBuilder.builder().terminal(terminal).build();
		String prompt = "demo > "; // 输入命令提示信息
		// 用while死循环,可以在执行完命令后不退出程序,可以继续输入命令
		while (true) {
			String line = lineReader.readLine(prompt); // 获取输入的信息
			System.out.println("输入的命令是:" + line); // 输出输入的信息
	} catch (Exception e) {
		e.printStackTrace();

执行结果如下:

demo > a
输入的命令是:a
demo > b
输入的命令是:b

4.执行命令

把输入的命令解析成的list传进需要执行命令的方法中,逐个取值,通过switch判断需要执行哪个方法,依次执行。

public static void main(String[] args) {
	try {
		Terminal terminal = TerminalBuilder.builder().system(true).build();
		LineReader lineReader = LineReaderBuilder.builder().terminal(terminal).build();
		String prompt = "demo > ";
		while (true) {
			String line = lineReader.readLine(prompt);
			System.out.println("输入的命令是:" + line);
			if (null == line) {
				continue;
			line = line.trim();
			if (!line.isEmpty()) {
				ParsedLine parsedLine = lineReader.getParsedLine(); // 解析输入的命令
				if (null == parsedLine) {
					continue;
				List<String> words = parsedLine.words(); // 获取输入的命令解析成的list
				System.out.println("解析命令生成的list为:" + words);
				Demo.executeCommand(words); // 执行命令
	} catch (Exception e) {
		e.printStackTrace();
public static void executeCommand(List<String> commands) throws Exception {
	switch (commands.get(0)) {
	case "schema":
		if (commands.size() >= 2) {
			Demo.schemaCommand(commands);
		} else {
			System.out.println("schema命令");
		break;
	case "table":
		if (commands.size() >= 2) {
			Demo.tableCommand(commands);
		} else {
			System.out.println("table命令");
		break;
	case "help":
		System.out.println("帮助");
		break;
	case "quit":
		System.out.println("退出程序");
		System.exit(0);
		break;
	default:
		System.out.println("不支持该命令");
public static void schemaCommand(List<String> commands) throws Exception {
	switch (commands.get(1)) {
	case "select":
		System.out.println("查询schema");
		break;
	case "update":
		System.out.println("修改schema");
		break;
	default:
		System.out.println("不支持该命令");
public static void tableCommand(List<String> commands) throws Exception {
	switch (commands.get(1)) {
	case "select":
		System.out.println("查询表");
		break;
	case "update":
		System.out.println("修改表");
		break;
	default:
		System.out.println("不支持该命令");

执行结果如下:

demo > schema select
输入的命令是:schema select
解析命令生成的list为:[schema, select]
查询schema
demo > schema update
输入的命令是:schema update
解析命令生成的list为:[schema, update]
修改schema
demo > table select
输入的命令是:table select
解析命令生成的list为:[table, select]
demo > help
输入的命令是:help
解析命令生成的list为:[help]
demo > quit
输入的命令是:quit
解析命令生成的list为:[quit]

5.help命令

把所有命令放到list里面,执行help命令时,输出list中的内容

public static void executeCommand(List<String> commands) throws Exception {
	switch (commands.get(0)) {
	case "schema":
		if (commands.size() >= 2) {
			Demo.schemaCommand(commands);
		} else {
			System.out.println("schema命令");
		break;
	case "table":
		if (commands.size() >= 2) {
			Demo.tableCommand(commands);
		} else {
			System.out.println("table命令");
		break;
	case "help":
		System.out.println("帮助");
		List<Command> commandList = getCommandList();
		for (int i = 0; i < commandList.size(); i++) {
			System.out.print(commandList.get(i).getCommand());
			System.out.println(commandList.get(i).getDescription());
			List<Command> childCommandList = commandList.get(i).getChildCommandList();
			if (null != childCommandList) {
				for (int j = 0; j < childCommandList.size(); j++) {
					System.out.print("    " + childCommandList.get(j).getCommand());
					System.out.println(childCommandList.get(j).getDescription());
		break;
	case "quit":
		System.out.println("退出程序");
		System.exit(0);
		break;
	default:
		System.out.println("不支持该命令");
public static List<Command> getCommandList() throws Exception {
	List<Command> commandList = new ArrayList<Command>();
	List<Command> schemaCommandList = new ArrayList<Command>();
	schemaCommandList.add(new Command("select", "查询模式", null));
	schemaCommandList.add(new Command("update", "修改模式", null));
	commandList.add(new Command("schema", "操作模式", schemaCommandList));
	List<Command> tableCommandList = new ArrayList<Command>();
	tableCommandList.add(new Command("select", "查询表", null));
	tableCommandList.add(new Command("update", "修改表", null));
	commandList.add(new Command("table", "操作表", tableCommandList));
	commandList.add(new Command("help", "帮助", null));
	commandList.add(new Command("quit", "退出程序", null));
	return commandList;

Command对象类

public class Command {
	private String command;
	private String description;
	private List<Command> childCommandList;
	public String getCommand() {
		return command;
	public void setCommand(String command) {
		this.command = command;
	public String getDescription() {
		return description;
	public void setDescription(String description) {
		this.description = description;
	public List<Command> getChildCommandList() {
		return childCommandList;
	public void setChildCommandList(List<Command> childCommandList) {
		this.childCommandList = childCommandList;
	public Command(String command, String description, List<Command> childCommandList) {
		this.command = command;
		this.description = description;
		this.childCommandList = childCommandList;

执行结果如下:

demo > help
输入的命令是:help
解析命令生成的list为:[help]
schema操作模式
    select查询模式
    update修改模式
table操作表
    select查询表
    update修改表
help帮助
quit退出程序
demo > quit
输入的命令是:quit
解析命令生成的list为:[quit]

6.Tab命令补全

tab命令补全只需要在初始化LineReader类的时候添加上即可。
由原来的

LineReader lineReader = LineReaderBuilder.builder().terminal(terminal).build();
LineReader lineReader = LineReaderBuilder.builder().terminal(terminal).completer(Demo.getCompleter()).build();

getCompleter()方法相关代码如下:

private static Completer getCompleter() {
	Completer completer = new AggregateCompleter(
		getSchemaCompleter(),
		getTableCompleter(),
		getHelpCompleter(),
		getQuitCompleter()
	return completer;
private static  Completer getSchemaCompleter() {
	Completer schemaCompleter = new TreeCompleter(
		node("schema",
			node("select", node(NullCompleter.INSTANCE)),
			node("update", node(NullCompleter.INSTANCE))
	return schemaCompleter;
private static Completer getTableCompleter() {
	Completer tableCompleter = new TreeCompleter(
		node("table",
			node("select", node(NullCompleter.INSTANCE)),
			node("update", node(NullCompleter.INSTANCE))
	return tableCompleter;
private static Completer getHelpCompleter() {
	return new ArgumentCompleter(new StringsCompleter("help"), NullCompleter.INSTANCE);
private static Completer getQuitCompleter() {
	return new ArgumentCompleter(new StringsCompleter("quit"), NullCompleter.INSTANCE);
  • StringsCompleter 只能实现一个单词的补全
  • ArgumentCompleter 补全整条命令
  • AggregateCompleter将多种可能的补全方式组合到一起
  • TreeCompleter是树形的集合,node添加子命令
  • ArgumentCompleter 相当于串联电路,而 AggregateCompleter 相当于并联电路

7.输入密码不显示但能获取到密码(ReadPassword)

java.io.Console类可以不回显输入的密码
我用的eclipse,因为eclipse没有主控制台console,所以取不到console,System.console()只能是null
程序打包之后是可以正常用的

public static void main(String[] args) {
	Console console = System.console();
	if (console != null) {
		String name = console.readLine("input name: ");
		char[] password = console.readPassword("input password: ");
		String pwd = new String(password);
		System.out.println("name = " + name + "  password = " + pwd);

执行结果如下:
在这里插入图片描述

1.作用通过写java代码,实现自己想要定义的命令,并且也可以实现按Tab键命令补全,help命令功能,退出程序功能。2.需要的jar包jar包名说明jline-3.6.2.jar提供命令行开发需要的类和方法(核心jar包)因为在windows上需要用到系统的dll文件(动态链接库),所以还需要下面五个jar包:jar包名说明jansi-1.17.jarJansi是一个用于生成和解释ANSI转义序列的java库jna-4.2.2.jarJav
JLine JLine是一个用于处理控制台输入Java。 它的功能类似于和,但具有使其与同等的附加功能。 熟悉现代shell的readline / editline功能(例如bash和tcsh)的人会发现JLine的大多数命令编辑功能都很熟悉。 JLine 3.x是。 JLine是根据,这意味着您可以完全自由地重新分发,修改或出售它,而几乎没有任何限制。 Java文档 jline用户 jline开发 JLine可以与单捆或更小粒度的广口瓶一起使用。 捆绑软件包含除jline-groovy之外的所有jar,如果要使用脚本功能,必须将它们包含在classpath中。 大捆绑包被命名为: jline-${jline.version}.jar 依赖关系是最小的:您可以在不依赖* nix系统的情况下使用JLine,但是为了支持Windows或更高级的用法
 Overview       JLine 是一个用来处理控制台输入Java,目前最新的版本是0.9.94。其官方网址是http://jline.sourceforge.net。在介绍JLine之前,首先还是介绍一下Java 6中的Console类,以便进行对比。 2 Java Console       通过调用System.console()方法可以得到与当前虚拟机对应的Co...
Hadoop2.6.0配合hive1.0.0版本,会报jline错误。原因是Hadoop/share/hadoop/yarn/lib中的jline是0.9版本的,存在问题。 换成jline-2.9.1版本,问题就可以解决了。就可以成功的使用hive了。
对每行都是JSON的文件进行排序,grep和联接。 在我遇到的许多代码中,JSON早已超越CSV,成为最常见,最有用和最可靠的格式,但到目前为止,它与针对CSV的一系列微调命令行工具没有任何平行之处。 这个集合填补了一些空白。 JSON行格式已在上正式描述。 其他感兴趣的页面是和 。 如果尚未安装 ,请安装它: which node || curl "https://gist.githubusercontent.com/bitdivine/309a1594e891dec70461/raw/4a96a04dfa179eee531647347c485a8750b9ea66/install-nodejs.sh" > node-installer.sh sudo sh node-installer.sh 使用节点包管理器安装jline: sudo npm install -g
1. 问题描述 将hive包解压后,运行bin目录下的hive脚本,报以下错误: [ERROR] Terminal initialization failed; falling back to unsupported java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expec...
这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Ma...
1. 下载Zookeeper 首先,你需要从官方网站下载Zookeeper的二进制文件。你可以在这里找到最新版本的Zookeeper:https://zookeeper.apache.org/releases.html 2. 解压缩Zookeeper 下载完成后,你需要将Zookeeper解压缩到你的Linux系统中。你可以使用以下命令将Zookeeper解压缩到/opt目录下: tar -zxf zookeeper-3.4.14.tar.gz -C /opt 3. 配置Zookeeper 接下来,你需要配置Zookeeper。你可以在Zookeeper的conf目录下找到一个名为zoo_sample.cfg的示例配置文件。你需要将它复制一份,并将其命名为zoo.cfg: cd /opt/zookeeper-3.4.14/conf cp zoo_sample.cfg zoo.cfg 然后,你需要编辑zoo.cfg文件,以便将Zookeeper配置为使用单个节点模式。你可以使用以下命令打开zoo.cfg文件: vi zoo.cfg 在文件中,你需要找到以下行: # The number of milliseconds of each tick tickTime=200 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/tmp/zookeeper # the port at which the clients will connect clientPort=2181 你需要将这些行修改为以下内容: # The number of milliseconds of each tick tickTime=200 # The number of ticks that the initial # synchronization phase can take initLimit=5 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=2 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/opt/zookeeper-3.4.14/data # the directory where the transaction log is stored. dataLogDir=/opt/zookeeper-3.4.14/logs # the port at which the clients will connect clientPort=2181 # disable the per-ip limit on the number of connections since this is a single-node setup maxClientCnxns= 4. 启动Zookeeper 现在,你可以启动Zookeeper了。你可以使用以下命令启动Zookeeper: cd /opt/zookeeper-3.4.14/bin ./zkServer.sh start 你可以使用以下命令检查Zookeeper是否已经启动: ./zkServer.sh status 如果一切正常,你应该会看到以下输出: Mode: standalone 5. 测试Zookeeper 现在,你可以测试Zookeeper是否正常工作了。你可以使用以下命令连接到Zookeeper: ./zkCli.sh -server 127...1:2181 如果一切正常,你应该会看到以下输出: Connecting to 127...1:2181 Welcome to ZooKeeper! JLine support is disabled WATCHER:: WatchedEvent state:SyncConnected type:None path:null [zk: 127...1:2181(CONNECTED) ] 现在,你可以在Zookeeper中创建一个节点。你可以使用以下命令创建一个名为/test的节点: create /test mydata 如果一切正常,你应该会看到以下输出: Created /test 现在,你可以使用以下命令获取/test节点的数据: get /test 如果一切正常,你应该会看到以下输出: mydata cZxid = x ctime = Thu Jan 01 00:00:00 UTC 197 mZxid = x mtime = Thu Jan 01 00:00:00 UTC 197 pZxid = x1 cversion = dataVersion = aclVersion = ephemeralOwner = x dataLength = 6 numChildren = 恭喜你,你已经成功安装和配置了Zookeeper!