JShell
来源:互联网 发布:编程金字塔图案 编辑:程序博客网 时间:2024/05/21 01:48
main.cpp
#include <iostream>#include "JShell.h"int main() { std::cout << "Hello, JShell!" << std::endl; JShell jShell; jShell.execute(); return 0;}
JShell.h
//// Created by JieWei on 8/22/16.//#ifndef UNIXAPI_JSHELL_H#define UNIXAPI_JSHELL_H#include <string>#include <map>#include <vector>#include "cmds.h"using namespace std;class JShell { const char* _promot = "JShell > "; int handleCommands(string line); int handleCommand(string command); int handleCommand(vector<string> segs, string input, string& output1, string& output2); int single_exec(vector<string> segs, string input, string& output1, string& output2); std::map<string, cmd_type> buildin_cmds; void log(string str);public: JShell(); void execute();};#endif //UNIXAPI_JSHELL_H
JShell.cpp
//// Created by JieWei on 8/22/16.//#include <iostream>#include <vector>#include <sstream>#include <unistd.h>#include <sys/wait.h>#include <cstdio>#include <algorithm>#include <memory>#include <fstream>#include <sstream>#include "JShell.h"#include "cmds.h"using namespace std;string& ltrim(string& s){ auto p = s.find_first_not_of(" "); if (p > 0){ s.erase(0, p); } return s;}vector<string> split(string& str){ vector<string> ret; stringstream ss(str); string buf; while(ss >> buf){ ret.push_back(buf); } return ret;}vector<string> split(const string &s, char delim) { vector<string> ret; stringstream ss(s); string item; while (getline(ss, item, delim)) { ret.push_back(item); } return ret;}string join(vector<string>& segs, string glue = " "){ stringstream ss; for(auto i = 0; i < segs.size(); ++i){ if(i != 0) ss << glue; ss << segs[i]; } return ss.str();}vector<string> split_cmd(string& str){ vector<string> ret; auto s1 = ltrim(str); if(s1.length() == 0){ return ret; } auto sp = s1.find_first_of(' '); if (sp == string::npos){ ret.push_back(str); ret.push_back(""); }else{ ret.push_back(str.substr(0, sp)); ret.push_back(str.substr(sp+1)); } return ret;}void write_file(string file, string content){ ofstream myfile; myfile.open (file); myfile << content; myfile.close();}string read_file(string file){ std::ifstream t(file); std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>()); return str;}void JShell::execute() { int st = 0; while(st != 100) { cout << _promot; string line; getline(cin, line); st = handleCommands(line); }}int JShell::handleCommand(string command) { // handle command with redirect 2 auto segs = split(command); string input_file, output1_file, output2_file; auto input_iter = find(segs.begin(), segs.end(), "<"); if (input_iter != segs.end()){ input_file = *(input_iter+1); segs.erase(input_iter, input_iter+2); log( "redirect input from " + input_file ); } auto output2_iter = find(segs.begin(), segs.end(), "2>"); if (output2_iter != segs.end()){ output2_file = *(output2_iter+1); segs.erase(output2_iter, output2_iter+2); log( "redirect output2 to " + output2_file ); } auto output1_iter = find(segs.begin(), segs.end(), ">"); if (output1_iter != segs.end()) { output1_file = *(output1_iter + 1); segs.erase(output1_iter, output1_iter + 2); log( "redirect output1 to " + output1_file ); } string input = ""; string output1 = ""; string output2 = ""; if (!input_file.empty()){ input = read_file(input_file); } auto cmd_ret = handleCommand(segs, input, output1, output2); if (!output1_file.empty()){ write_file(output1_file, output1); }else{ if (!output1.empty()) cout << output1 << endl; } if (!output2_file.empty()){ write_file(output2_file, output2); }else{ if (!output2.empty()) cout << output2 << endl; } return cmd_ret;}JShell::JShell() { // initialize buildin commands buildin_cmds["cd"] = &cd; buildin_cmds["echo"] = &echo; buildin_cmds["cmd1"] = &cmd1;}int JShell::handleCommand(vector<string> segs, string input, string& output1, string& output2) { // handle commmand with build in cmds string command = join(segs); auto argv_segs = split_cmd(command); int process_ret = 0; if(segs.size() == 0){ log("Empty command"); return 0; }else{ string cmd = segs[0]; if (cmd == "exit") { return 100; } if (buildin_cmds.find(cmd) != buildin_cmds.end()){ log(cmd + " is a built in command!"); process_ret = buildin_cmds[cmd](argv_segs[1].c_str(), output1); }else{ process_ret = single_exec(segs, input, output1, output2); } if (process_ret != 0) { stringstream ss; ss << process_ret; log(cmd + " return non-zero: " + ss.str()); } } return 0;}int JShell::single_exec(vector<string> segs, string input, string& output1, string& output2) { int pipe_in[2]; int pipe_out1[2]; int pipe_out2[2]; pipe(pipe_in); pipe(pipe_out1); pipe(pipe_out2); auto pid = fork(); if (pid == 0){ // child char** argv = new char*[segs.size()+1]; for(int i = 0; i < segs.size(); ++i){ argv[i] = const_cast<char*>(segs[i].c_str()); } argv[segs.size()] = NULL; if(!input.empty()){ dup2(pipe_in[0], STDIN_FILENO); close(pipe_in[1]); } close(pipe_out1[0]); dup2(pipe_out1[1], STDOUT_FILENO); close(pipe_out2[0]); dup2(pipe_out2[1], STDERR_FILENO); int ret = execvp(segs[0].c_str(), argv); delete [] argv; exit(ret); }else{ // parent char buf[10240]; // input if(!input.empty()){ close(pipe_in[0]); write(pipe_in[1], input.c_str(), input.length()); close(pipe_in[1]); } close(pipe_out1[1]); auto len = read(pipe_out1[0], buf, sizeof(buf)); buf[len] = 0; output1 = buf; close(pipe_out2[1]); len = read(pipe_out2[0], buf, sizeof(buf)); buf[len] = 0; output2 = buf; int child_ret; wait(&child_ret); return child_ret; }}void JShell::log(string str) { // JShell's output format cout << "*[" << str << "]*" << endl;}int JShell::handleCommands(string line) { // handles command with pipe int ret = 0; auto cmds = split(line, '|'); switch(cmds.size()){ case 1: { ret = handleCommand(line); break; } case 2: { log("pipe command"); string inp, output1, output2; auto cmd1 = split(cmds[0]); handleCommand(cmd1, inp, output1, output2); string cmd2_output1, cmd2_output2; auto cmd2 = split(cmds[1]); ret = handleCommand(cmd2, output1 + output2, cmd2_output1, cmd2_output2); if (!cmd2_output1.empty()) cout << cmd2_output1 << endl; if (!cmd2_output2.empty()) cout << cmd2_output2 << endl; break; } default: { log("Unsupport multi pipe!"); } } return ret;}
cmds.h
//// Created by JieWei on 8/22/16.//#ifndef UNIXAPI_CMDS_H#define UNIXAPI_CMDS_H#include <iostream>using namespace std;typedef int (*cmd_type)(const char*, string&);int echo(const char* argv, string& output);int cd(const char *argv, string& output);int cmd1(const char *argv, string& output);#endif //UNIXAPI_CMDS_H
cmds.cpp
//// Created by JieWei on 8/22/16.//// cmds.cpp contains commmands like binary in /usr/bin#include <iostream>#include <unistd.h>#include "cmds.h"int cd(const char *argv, string& output) { int ret = chdir(argv); output = string("I'm cd, i'm going to ") + argv; return ret;}int echo(const char* argv, string& output) { output = string(argv) + "\n"; return 0;}int cmd1(const char* argv, string& output) { output = "cmd1... do nothing.\n"; return 0;}// add more built in commands here...
0 0
- jShell
- JShell
- JShell
- Java9 中的Jshell 操作
- Java9之Jshell入门
- java9的REPL环境--JShell
- JavaOne 2016——观众得以一睹JShell的威力
- Java SE 9(JDK9)环境安装及交互式编程环境Jshell使用示例
- Java SE 9(JDK9)环境安装及交互式编程环境Jshell使用示例
- Java SE 9(JDK9)环境安装及交互式编程环境Jshell使用示例
- Zeppelin 使用JShell实现java解释器,从此用notebook写java
- ios NSFetchedResultsController的使用
- [Gym - 101064F Metal detector] 递推
- TensorFlow安装所遇到的问题
- 程序员软技能
- OnItemClickListener 条目的点击侦听
- JShell
- 《训练指南》大白 二维几何基础 基本公式(模板)
- 在Azure上部署squid的教程
- java中的泛型总结
- RPC应用的java实现
- QT+OpenCv实现在410c开发板上实现视频目标追踪预研——目标跟踪算法选择
- uva 536Tree Recovery
- 在活动中使用menu
- POJ 3273 Conscription(最小生成树)