Table of Contents
Creating a simple shell in C is a fundamental exercise for understanding how operating systems handle user commands and process management. In this article, we will explore how to parse user input and execute commands using basic C programming techniques.
Understanding the Basics of a Shell
A shell acts as an interface between the user and the operating system. It reads user commands, interprets them, and then executes the corresponding processes. Building a basic shell helps to understand core concepts like input parsing, process creation, and command execution.
Parsing User Input
To parse commands, you need to read input from the user and split it into tokens. This typically involves using functions like fgets to read a line and strtok to split it into command and arguments.
Here’s a simple example of parsing input:
char input[100];
char *args[10];
int i;
printf("Enter command: ");
fgets(input, 100, stdin);
args[0] = strtok(input, " \n");
i = 1;
while ((args[i] = strtok(NULL, " \n")) != NULL) {
i++;
}
args[i] = NULL; // Null-terminate the argument list
Executing Commands
Once the input is parsed into command and arguments, you can use fork and execvp to create a new process and execute the command.
Example code to execute the command:
pid_t pid = fork();
if (pid == 0) {
// Child process
execvp(args[0], args);
perror("exec failed");
exit(1);
} else if (pid > 0) {
// Parent process
wait(NULL);
} else {
perror("fork failed");
}
Putting It All Together
By combining input parsing and process execution, you can build a simple shell loop:
while (1) {
printf("myshell> ");
fgets(input, 100, stdin);
args[0] = strtok(input, " \n");
if (args[0] == NULL) continue;
if (strcmp(args[0], "exit") == 0) break;
i = 1;
while ((args[i] = strtok(NULL, " \n")) != NULL) {
i++;
}
args[i] = NULL;
pid_t pid = fork();
if (pid == 0) {
execvp(args[0], args);
perror("exec failed");
exit(1);
} else if (pid > 0) {
wait(NULL);
} else {
perror("fork failed");
}
}
This simple shell demonstrates core concepts of command parsing and process management in C. Enhancements like handling background processes, input/output redirection, and command piping can be added for more advanced features.