# gen-shell
-![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fbuild.bhojwani.org%2Fjob%2Fgen-shell%2F)
-A work in progress generic shell. This is a very reduced fork of [taskshell](https://github.com/GothenburgBitFactory/taskshell)
+![Jenkins](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fbuild.bhojwani.org%2Fjob%2Fgen-shell%2F)
+=== WORK IN PROGRSS ===
+A simple way to turn any command into a shell with arrow key/history suppoert. This is a fork of [taskshell](https://github.com/GothenburgBitFactory/taskshell) with a highly reduce codebase.
+
+## Usage
+Just put the command that you want to repeat as the argument
## Installation
Binaries can be downloaded [from here](https://build.bhojwani.org/job/gen-shell/lastSuccessfulBuild/artifact/build/src/gen-shell). Note that these binaries are compiled against libreadline7, so if your system only has libreadline8, you should symlink 8 to 7 with `sudo ln -s /usr/lib/x86_64-linux-gnu/libreadline.so.8.0 /usr/lib/x86_64-linux-gnu/libreadline.so.7`. This isn't a great solution, but it gets the job done.
- g++
- libreadline development files
-```
+```bash
git clone https://codeberg.org/armaan/gen-shell
cd gen-shell
-cmake --build .
+cmake .
+make
sudo cp src/gen-shell /usr/bin/
```
Or if you don't have root access, you can subsitute the last line with
#include <readline/history.h>
#endif
-std::string promptCompose ();
+using namespace std;
+std::string promptCompose();
-const std::string getResponse (const std::string& prompt)
-{
- std::string response {""};
+const std::string getResponse(const std::string & prompt) {
+ std::string response {
+ ""
+ };
// Display prompt, get input.
-#ifdef HAVE_READLINE
- char *line_read = readline (prompt.c_str ());
- if (! line_read)
- {
+ #ifdef HAVE_READLINE
+ char * line_read = readline(prompt.c_str());
+ if (!line_read) {
std::cout << "\n";
response = "<EOF>";
- }
- else
- {
+ } else {
// Save history.
- if (*line_read)
- add_history (line_read);
+ if ( * line_read)
+ add_history(line_read);
- response = std::string (line_read);
- free (line_read);
+ response = std::string(line_read);
+ free(line_read);
}
-#else
+ #else
std::cout << prompt;
- std::getline (std::cin, response);
- if (std::cin.eof () == 1)
- {
+ std::getline(std::cin, response);
+ if (std::cin.eof() == 1) {
std::cout << "\n";
response = "<EOF>";
}
-#endif
+ #endif
return response;
}
-////////////////////////////////////////////////////////////////////////////////
-static int commandLoop (bool autoClear)
-{
- // Compose the prompt.
- auto prompt = promptCompose ();
-
- // Display prompt, get input.
- auto command = getResponse (prompt);
-
- if (autoClear)
- std::cout << "\033[2J\033[0;0H";
-
- int status = 0;
- if (! isatty (fileno (stdin)) && command == "")
- {
- status = -1;
- }
- else if (command != "")
- {
- // Dispatch command.
- if (command == "<EOF>") status = -1;
- else if (command != "")
- {
- command = command;
- std::cout << "[" << command << "]\n";
- system (command.c_str ());
- }
- }
-
- return status;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-int main (int argc, const char** argv)
+int main(int argc, char** argv)
{
int status = 0;
- // Lightweight version checking that doesn't require initialization or any I/O.
- if (argc == 2 && !strcmp (argv[1], "--version"))
- {
- std::cout << VERSION << "\n";
+ string root_cmd;
+ for (int i = 1; i < argc; ++i) {
+ root_cmd +=argv[i];
}
- else
- {
- try
- {
- bool autoClear = false;
- std::string input;
- std::string output;
- autoClear = (output == "true\n" ||
- output == "1\n" ||
- output == "y\n" ||
- output == "yes\n" ||
- output == "on\n");
- while ((status = commandLoop (autoClear)) == 0)
- ;
- }
+ while (status == 0) {
+ // Compose the prompt.
+ auto prompt = promptCompose();
- catch (const std::string& error)
- {
- std::cerr << error << "\n";
- status = -1;
- }
+ // Display prompt, get input.
+ auto command = getResponse(prompt);
- catch (...)
+ int status = 0;
+ if (command != "")
{
- std::cerr << "Unknown error." << "\n";
- status = -2;
+ // Dispatch command.
+ if (command == "<EOF>") status = 1;
+ else if (command != "")
+ {
+ if (argc == 0) {
+ string whole_command=command;
+ std::cout << "[" << command << "]\n";
+ system (command.c_str ());
+ }
+ else {
+ string whole_command = root_cmd + " " + command;
+ std::cout << "[" << whole_command << "]\n";
+ system (whole_command.c_str ());
+ }
+ }
}
+ if (status == 1)
+ return 0;
}
-
- // Returning -1 drops out of the command loop, but gets translated to 0 here,
- // so that there is a clean way to exit.
- return status == -1 ? 0 : status;
}
////////////////////////////////////////////////////////////////////////////////
--- /dev/null
+////////////////////////////////////////////////////////////////////////////////
+//
+// Copyright 2006 - 2017, Paul Beckingham, Federico Hernandez, 2020 Armaan Bhojwani
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+//
+// http://www.opensource.org/licenses/mit-license.php
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include <cmake.h>
+#include <iostream>
+#include <vector>
+#include <string>
+#include <cstring>
+#include <cstdio>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_READLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+
+using namespace std;
+std::string promptCompose ();
+
+const std::string getResponse (const std::string& prompt)
+{
+ std::string response {""};
+
+ // Display prompt, get input.
+#ifdef HAVE_READLINE
+ char *line_read = readline (prompt.c_str ());
+ if (! line_read)
+ {
+ std::cout << "\n";
+ response = "<EOF>";
+ }
+ else
+ {
+ // Save history.
+ if (*line_read)
+ add_history (line_read);
+
+ response = std::string (line_read);
+ free (line_read);
+ }
+#else
+ std::cout << prompt;
+ std::getline (std::cin, response);
+ if (std::cin.eof () == 1)
+ {
+ std::cout << "\n";
+ response = "<EOF>";
+ }
+#endif
+
+ return response;
+}
+
+int commandLoop ()
+{
+ // Compose the prompt.
+ auto prompt = promptCompose ();
+
+ // Display prompt, get input.
+ auto command = getResponse (prompt);
+
+ int status = 0;
+ if (! isatty (fileno (stdin)) && command == "")
+ {
+ status = -1;
+ }
+ else if (command != "")
+ {
+ // Dispatch command.
+ if (command == "<EOF>") status = -1;
+ else if (command != "")
+ {
+ command = command;
+ std::cout << "[" << command << "]\n";
+ system (command.c_str ());
+ }
+ }
+
+ return status;
+}
+
+int main ()
+// int main (int argc, const char** argv)
+{
+ int status = 0;
+
+ while (status == 0)
+ commandLoop();
+
+ return status == -1 ? 0 : status;
+}
+
+////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
std::string promptCompose ()
{
- return ">>>";
+ return "% ";
}
////////////////////////////////////////////////////////////////////////////////