Le shell est comme un programme qui reçoit les entrées de commande du clavier de l'utilisateur et les envoie à une machine à exécuter par le noyau. Il vérifie également si les entrées de commande de l'utilisateur sont correctes. Il pourrait s'agir d'une interface de ligne de commande, comme celle que nous créerons, ou une interface utilisateur graphique, comme des logiciels normaux tels que Microsoft Office ou Adobe Suite.
Ce tutoriel vous guidera à travers les étapes de la création d'un shell simple indépendant en C. Après avoir terminé ce tutoriel, vous devriez avoir une meilleure compréhension des différents processus et fonctions impliqués, ainsi qu'une façon claire réalisable de coder par vous-même.
Quelle est la durée de vie de base de la coquille?
Au cours de sa durée de vie, une coquille accomplit trois tâches majeures.
- Initialiser: À ce stade, un shell typique se lira et exécutera son ensemble de fichiers de configuration. Ceux-ci modifient le comportement de la coquille.
- Interpréter: Le shell lit ensuite les commandes de «stdin» et les exécute.
- Mettre fin: Après l'exécution de ses commandes, le shell effectue l'une des commandes d'arrêt, libère n'importe quelle mémoire et se termine.
Ces étapes sont générales et peuvent être applicables à un large éventail de programmes, mais nous les utiliserons comme base de notre shell. Notre shell sera si basique qu'il n'y aura pas de fichiers de configuration et pas de commande d'arrêt. Donc, nous allons simplement exécuter la fonction de boucle puis sortir. Cependant, il est essentiel de se rappeler que la durée de vie du programme est plus qu'une simple boucle.
Comment créer une obus simple en c?
Nous créerons un shell de base en C qui démontrera les principes fondamentaux de son fonctionnement. Parce que son objectif est la démonstration plutôt que la complétude ou même la forme physique à usage occasionnel, il a un certain nombre de limitations, y compris
- Toutes les commandes doivent être tapées sur une seule ligne.
- L'espace doit être utilisé pour séparer les arguments.
- Il n'y aura pas de citation ou d'échappement blanc.
- Il n'y a pas de tuyauterie ou de réacheminement.
- Les seuls intégrés sont «CD», «Help» et «Exit».
Jetez maintenant un œil à un programme C qui construit une obus simple.
#inclure
#inclure
#inclure
#inclure
#inclure
#inclure
int komal_cd (char ** args);
int komal_help (char ** args);
int komal_exit (char ** args);
char * boxed_in_string [] =
"CD",
"aider",
"sortie"
;
int (* boxed_in_function []) (char **) =
& komal_cd,
& komal_help,
& komal_exit
;
int komal_builtins ()
return sizeof (boxed_in_string) / sizeof (char *);
int komal_cd (char ** args)
if (args [1] == null)
fprintf (stderr, "komal: argument attendu à" cd "\ n");
autre
if (chdir (args [1]) != 0)
Perror ("Komal");
retour 1;
int komal_help (char ** args)
int i;
printf ("Ceci est une simple construction de shell C par Komal Batool \ n");
printf ("Type des noms et arguments du programme, et appuyez sur Entrée.\ n ");
printf ("Les éléments suivants sont construits: \ n");
pour (i = 0; i < komal_builtins(); i++)
printf ("% s \ n", construit_in_string [i]);
printf ("Utilisez la commande man pour des informations sur d'autres programmes.\ n ");
retour 1;
int komal_exit (char ** args)
retour 0;
int komal_launch (char ** args)
pid_t pid;
statut int;
pid = fork ();
if (pid == 0)
if (execvp (args [0], args) == -1)
Perror ("Komal");
exit (exit_failure);
sinon if (pid < 0)
Perror ("Komal");
autre
faire
WaitPid (pid, & statut, wunttraced);
alors que (!Femmexited (statut) && !Wifsignaled (statut));
retour 1;
int komal_execute (char ** args)
int i;
if (args [0] == null)
retour 1;
pour (i = 0; i < komal_builtins(); i++)
if (strcmp (args [0], boxed_in_string [i]) == 0)
return (* boxed_in_function [i]) (args);
return komal_launch (args);
char * komal_read_line (void)
#ifdef komal_use_std_getline
char * line = null;
ssize_t bufSize = 0;
if (getline (& line, & bufsize, stdin) == -1)
if (feof (stdin))
exit (exit_success);
autre
perror ("Komal: getline \ n");
exit (exit_failure);
La ligne de retour;
#autre
#define komal_rl_bufSize 1024
int bufsize = komal_rl_bufSize;
position int = 0;
char * tampon = malloc (sizeof (char) * bufsize);
INT C;
si (!amortir)
fprintf (stderr, "komal: erreur d'allocation \ n");
exit (exit_failure);
tandis que (1)
c = getchar ();
if (c == eof)
exit (exit_success);
else if (c == '\ n')
tampon [position] = '\ 0';
tampon de retour;
autre
tampon [position] = c;
position ++;
if (position> = bufsize)
bufSize + = komal_rl_bufSize;
tampon = realloc (tampon, bufsize);
si (!amortir)
fprintf (stderr, "komal: erreur d'allocation \ n");
exit (exit_failure);
#fin si
#define komal_tok_bufSize 64
#define komal_tok_delim "\ t \ r \ n \ a"
char ** komal_split_line (ligne de char *)
int bufsize = komal_tok_bufSize, position = 0;
tokens char ** = malloc (bufsize * sizeof (char *));
token char *, ** tokens_backup;
si (!jetons)
fprintf (stderr, "komal: erreur d'allocation \ n");
exit (exit_failure);
token = strtok (ligne, komal_tok_delim);
Pendant (jeton != Null)
jetons [position] = jeton;
position ++;
if (position> = bufsize)
bufSize + = komal_tok_bufSize;
tokens_backup = tokens;
tokens = realloc (jetons, bufSize * sizeof (char *));
si (!jetons)
gratuit (tokens_backup);
fprintf (stderr, "komal: erreur d'allocation \ n");
exit (exit_failure);
token = strtok (null, komal_tok_delim);
jetons [position] = null;
Tokens de retour;
void komal_loop (void)
char * ligne;
char ** args;
statut int;
faire
printf (">");
line = komal_read_line ();
args = komal_split_line (ligne);
status = komal_execute (args);
ligne gratuite);
libre (args);
while (status);
int main (int argc, char ** argv)
komal_loop ();
return exit_success;
Description du code
Le code ci-dessus est une simple implémentation d'un shell de ligne de commande écrite en C. La coquille est nommée "Komal", Et il peut exécuter des commandes intégrées telles que «CD», «Aide» et «Exit», ainsi que des commandes externes. La fonction principale du programme est le "Komal_loop" fonction, qui boucle en continu, lisant l'entrée de l'utilisateur via le "Komal_read_line" fonction, divisant l'entrée en arguments individuels en utilisant le "Komal_split_line" fonction et exécution de la commande à l'aide du "Komal_execute" fonction.
Le "Komal_execute" La fonction vérifie si la commande est une commande intégrée, et si oui, il exécute la fonction intégrée correspondante. Si la commande n'est pas une commande intégrée, il exécute une commande externe en fournissant un processus d'enfant et en appelant le «Execvp» Appel système pour remplacer l'espace mémoire du processus de l'enfant par le programme souhaité.
Le "Komal_CD", "Komal_help", et "Komal_exit" Les fonctions sont les trois fonctions intégrées qui peuvent être exécutées par l'utilisateur. "Komal_cd" Modifie le répertoire de travail actuel, "Komal_help" fournit des informations sur le shell et ses commandes intégrées, et "Komal_exit" sort de la coquille.
Sortir
Conclusion
La construction d'un shell simple en C implique de comprendre comment analyser et exécuter les commandes, gérer les entrées et les sorties de l'utilisateur, et gérer les processus à l'aide d'appels système comme Fork et Execvp. Le processus de création d'un shell nécessite une compréhension approfondie du langage de programmation C et du système d'exploitation UNIX. Cependant, avec l'aide des étapes et de l'exemple fourni dans le guide ci-dessus, on peut créer un shell de base qui peut gérer la saisie des utilisateurs et exécuter les commandes.