Reputation: 4116
For my class I have to create a basic shell similar to bash that will allow the user to call commands like ls, sleep, etc. I am looking for resources on how to do this: tutorials, help text, sample code or even just some general information on how to get started. Does anyone have an links or info to help me out?
Upvotes: 23
Views: 80590
Reputation: 744
If you are starting , try http://stephen-brennan.com/2015/01/16/write-a-shell-in-c/ and further for detailed knowledge http://www.gnu.org/software/libc/manual/html_node/Data-Structures.html#Data-Structures .
Also , while learning how to program a shell using C/C++ make a habit to refer man pages of commands.
Upvotes: 2
Reputation: 215367
You could look at BusyBox for some very small shell implementations.
Upvotes: 2
Reputation: 1
Lowball answer:
If the program is very simple, then simple system calls can be implemented script-like with the command "system("putdesiredcommandhere");
"
When you install "printf
" in a program, you are doing a simple system call, with the help of stdio.h.
Small code sample follows.
#include <stdio.h>
#include <stdlib.h>
main ()
{
system ("clear");
system ("echo this is an example of a basic system call");
printf ("just as you've always done.\n");
return 0;
}
Using that method, you could transcribe bash or csh scripts into a c program. It would require using a system call for each line in the script.
Upvotes: 0
Reputation: 5431
It really depends on how simple your shell has to be. If you don't need job control (i.e. backgrounding) or pipes then it is very simple. Here is an example:
#include <stdio.h>
#include <stdlib.h>
#define MAX_LENGTH 1024
int main(int argc, char *argv[]) {
char line[MAX_LENGTH];
while (1) {
printf("$ ");
if (!fgets(line, MAX_LENGTH, stdin)) break;
system(line);
}
return 0;
}
You can exit from the above example with CTRL-D. To add built-in commands like exit or cd you would have to tokenize the line using strtok() and look at the first token. Here is a more complicated example with those commands added:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef _WIN32
#include <windows.h>
#define chdir _chdir
#else
#include <unistd.h>
#endif
#define MAX_LENGTH 1024
#define DELIMS " \t\r\n"
int main(int argc, char *argv[]) {
char *cmd;
char line[MAX_LENGTH];
while (1) {
printf("$ ");
if (!fgets(line, MAX_LENGTH, stdin)) break;
// Parse and execute command
if ((cmd = strtok(line, DELIMS))) {
// Clear errors
errno = 0;
if (strcmp(cmd, "cd") == 0) {
char *arg = strtok(0, DELIMS);
if (!arg) fprintf(stderr, "cd missing argument.\n");
else chdir(arg);
} else if (strcmp(cmd, "exit") == 0) {
break;
} else system(line);
if (errno) perror("Command failed");
}
}
return 0;
}
You could extend this by adding more build-in commands or by supporting things like cd with out arguments to change to your home directory. You could also improve the command prompt by adding information such as the current directory.
As a side note, an easy way to add a command history and line editing features is to use the GNU readline library.
Upvotes: 12
Reputation:
I wrote a very basic shell for the HelenOS project. It has the following features:
Most of it is implemented on a very simple re-usable framework built around function pointers. At the minimum, you'll need a built in 'exit' or 'quit' so someone can actually get out of the shell, plus 'cd' and 'pwd'. An 'export' / 'declare' built in would also make sense.
You can look at the code (BSD) licensed here. Or download the repo, it's in uspace/app/bdsh. I can probably dig up the last working Linux version, prior to when I ported it if you need it. The biggest difference is the HelenOS version uses a home grown line editor, task_spawn() instead of execve() / posix_spawn(), etc. The rest is portable. It was originally designed just to make testing of features easy and interactive. I didn't implement job control, as it wasn't needed. That could be achieved trivially, however.
If you want to study a 'real' shell, I highly recommend looking at dash
, you'll find it much simpler to grasp than diving straight into the code of bash.
Anecdotally, 'bdsh' stands for 'brain dead shell'.
Upvotes: 5
Reputation: 37928
Bash provides very few commands on its own: cd
, pushd
, popd
, the variable handling routines (set
and $x
), and all of the control flow items like loops and conditionals. Almost all other commands are found in the $PATH
.
Unless the assignment states otherwise, ignore variables and control flow. Just provide a REPL that looks in $PATH
and executes whatever the user enters (presumably through posix_spawn()
) and pass along the command-line arguments.
Upvotes: 0