User:Kenny
Command Line Interface
The Command Line Interface of an operating system provides the most basic, but very powerful method of controlling the system. When writing an operating system, you should consider writing a command line interface after you have have a stable kernel, can output to the screen, and can read from the keyboard. Advanced topics such as multi-tasking and memory management aren't essential.
Your first command line interface is likely to be a function which can read the keyboard, compare the entered string to a list of known commands, and run another function based on the entry.
For a slightly more advanced command line interface, you will probably want to use the common structure of command line interfaces which is split into two components, the console, and the command interpreter (also called the shell) itself.
Console
The console, or terminal, is the environment which runs command line programs. It provides a standard input stream, a standard output stream, a standard error stream, and a set of environment variables.
In a basic system, the standard input device is the keyboard, and the standard output and error streams appear as text on the screen.
In C from the point of view of a command line program, the standard input stream (referred to as stdin), the standard output stream (stdout) and the standard error stream (stderr) are FILE structures. The stdin stream is read using the fread() function, and the stdout and stderr streams are written to using fwrite() or fprintf(). These operations allow a command line program to interact with the user.
More complicated systems can use any character device for a console's input and output, for example a terminal could be opened using a serial port so that a serially connected terminal could run commands, a command could have its output sent to a file or a printer, or the output could be sent to a null device (discarded).
Command Interpreter
All command line tools operate in very much the same way. They expect to be provided with a standard input stream, a standard output stream, a standard error stream, and a set of environment variables. Each tool reads characters from the standard input (usually the keyboard), performs some task, outputs information to the standard output or standard error streams (usually the screen), then exits.
The command interpreter itself is no different. When run, it goes into a loop where it outputs a prompt to stdout then waits for a command to be entered on stdin, it then runs the command, and goes back to display the next prompt. It does this until it's given a command to exit.
Because a command interpreter behaves exactly like any other command line tool, it is possible to run one command interpreter from within another. The second interpreter will take control until it is exited, at which point the user will return to the first command interpreter just as if they had run any other command.
Many Unix-based systems offer a selection of command interpreters, such as sh, ash, bash, ksh
Many command interpreters offer additional features, such as the ability to review and repeat previous commands, or to auto-complete file names.
Redirection
Most command line interpreters feature the ability to redirect the stdin, stdout and stderr streams for a given command.
From the user's point of view, they specify additional command line arguments with the "<" or ">" character followed by the name of a device or file, the command line interpreter then read input from or writes output (stdout) to that location.
From the point of view of the command interpreter, it detects the special redirection argument and attempts to open the location specified by using fopen(). This then creates a FILE structure that the command line interpreter passes to the invoked command as stdin or stdout as appropriate. The command then reads these as normal as has no idea ( and doesn't care ) that the input or output is being redirected.
Piping Commands
A logical extension of redirection is the concept of piping. This is taking the output from one command and feeding to a subsequent command as its input.
The user specifies the commands in the order they are to be executed and puts a pipe symbol "|" between each. For example, the user can write "ls | more" to run the ls command and provide it's output to the more command. The benefit to the user in this example is that the more command will display the information one screen at a time and wait for the user to review each before proceeding.
From the command interpreter's side, it creates an temporary buffer which can be written or read through a FILE structure, and passes it as the stdout of the first command. The first command runs and pushes the data into the buffer. Once the first command finishes, the command interpreter rewinds the temporary buffer and passes it as the stdin to the next command. If necessary, the command interpreter will have created a second buffer to capture the output of the second command to pipe to a third command.
In some command interpreters, such as PowerShell, the input and output of commands isn't limited to data being written to a stream, but instead can contain complete programming objects.
Writing a Command Line Interface
As mentioned, a command line interface will need the following components:
- Enough of the standard C library to implement
- the fread() function
- the fwrite() function
- the FILE structure
- (optional) the fprintf() function
- The Console component, comprising
- a FILE structure instance representing the keyboard input, supporting converting a key-press to a character and buffering it.
- a FILE structure instance representing the screen output, supporting writing a character, deleting a character, and moving to a new line.
- The Command interpreter, comprising
- a buffer to store the input until the user presses enter
- A lookup table or other list of commands to be compared the entered string.
TODO
- Comment on how changing the terminal capabilities may affect programs (changing font size, resizing window etc.) such as more.
- Comment on how programs may want to influence the terminal capabilities (e.g. resize the window).
- Comment on special characters that can affect the position of the cursor or the colour of the text etc. (escape sequences).
Further Reading
Wikipedia entry for Unix Shell Gives background information on command line interpreters in general.