nsh is yet another shell built mainly to better my understanding of operating systems, parsing, and the C language. Cleverly (not actually clever) named similarly to other popular shells like zsh, csh, ksh...nsh wants to get in on that sweet, sweet clickity-clack, black and white action.
Firstly, I only guarantee that this program will run absolutely correctly on Ubuntu Linux 14.04. I'm sure it'll compile correctly on other versions of Linux. I was actually able to compile it with Cygwin on Windows 10 and basic functionality was there, though editing commands didn't seem to work.
Besides the C standard library all nsh uses is make
to actually build the project. Of course you need the make
package to do this, so install it somehow. I recommend:
sudo apt-get install make
Once you've created the executable for the project go ahead and just run it with ./nsh
. Hooray! It should work just like a normal shell like bash
. You can run, and pipe, any number of commands built in with Linux like ls
, cd
, etc. The input isn't limited so you can type in many commands at once, although scripting isn't supported yet. I need to work a lot more on the parser and implement an interpreter before that happens.
Hey, how about a feature list to get your motor running!
Use as many pipes as you like to redirect input to the next commands output.
Type as much as you like and feel your heart strings get pulled as the program doesn't crash.
As of right now the custom commands supported are:
merge
pause
history
cd
quit
Besides the C standard library and the make
utility this entire project doesn't use any external libraries. I might look around and see if there's an easily available library that will interface with the terminal you're using independent of what OS it is so that it might work better on Windows.
If you're actually interested in contributing go ahead and fork the project and then submit a pull
request.
Here are some bugs that exist and some features I'd like to add as of this moment.
-
Tabs, among other special characters, do not register correctly
All there is to do in this regard really is to add additional code which does what the corresponding button press should do. To remove this "bug", code could just be written to ignore unknown characters. Tabs are a little more complicated because we would like those to auto-complete our query but for now simply adding extra spaces correctly would be adequate. This shell only supports ASCII characters as well, so any unicode characters don't register correctly either. That would be nice to add eventually as well.
-
Empty input isn't handled correctly
When the user type nothing or just spaces it attempts to execute some file with that label it seems. Could probably just add a special case in the parser for this.
-
Custom Commands Not Implemented
As of right now the only commands implemented are "quit". That's pretty bad.
-
Custom Commands Inefficient
For parsing custom commands, the current method is to strcmp() the string entered by the user multiple times in an if-elseif-else chain until the correct command is found. This is horribly inefficient and a hash would do a much better job of it. I might implement this in C++ because I really don't want to write a hash library myself.
-
Commands History Implemented Poorly
The user's history of commands is currently stored in an array and each time the user adds a new command, the array copies each position to the next and places the newest commands in the [0] element. That's horrible. Clearly the commands history works a bit like a double-ended queue which is typically implemented with a linked list. Not only that but a linked list is just more efficient for this action. So ideally I would like to reimplement the commands history in this fashion.
-
Make tab auto-complete as is expected in most shells
Could probably do this just using
ls
andgrep
and then retrieve the output. If there's only one file just auto-complete the line with it's name, otherwise print the output. -
Support for turning on or off certain features
With other shells certain shell features (such as shell history) can be turned on or off. Currently there is no setup at all for this.
-
Parsing/Expanding Commands
On a grander scale, such as interpreting a shell file, this will require a lot of effort and likely require a good amount of knowledge about compilers/interpreters. However, on a smaller scale (simply implementing custom commands), this isn't as difficult. For example, when a user types "merge ... > " for example, ideally we would like to convert this into "cat file1 file2 ... fileN" and then redirect the output from STDOUT to a file descriptor representing fileN+1. I actually took care of this already for several custom commands. It's not too hard to add additional custom commands as of this moment.
As of right now this string manipulation this requires is incompatible with the way the strings are stored and later freed in memory. This is easily fixable and will be taken care of soon by me.
Just me woohoo!