La shell è come un programma che riceve input di comando dalla tastiera dell'utente e li invia a una macchina da eseguire dal kernel. Verifica anche per vedere se gli input di comando dell'utente sono corretti. Potrebbe essere un'interfaccia di comando, come quella che creeremo, o un'interfaccia utente grafica, come il normale software come Microsoft Office o Adobe Suite.
Questo tutorial ti guiderà attraverso le fasi della creazione di un semplice shell indipendente in c. Dopo aver completato questo tutorial, dovresti avere una migliore comprensione dei vari processi e funzioni coinvolti, nonché un chiaro modo praticabile per codificare da solo.
Qual è la vita di base del guscio?
Durante la sua durata della vita, un guscio svolge tre compiti importanti.
- Inizializzare: In questa fase, una shell tipica leggerà e eseguirà il suo set di file di configurazione. Questi alterano il comportamento del guscio.
- Interpretare: La shell quindi legge i comandi da "stdin" ed li esegue.
- Terminare: Dopo l'esecuzione dei suoi comandi, la shell esegue uno qualsiasi dei comandi di spegnimento, libera qualsiasi memoria e termina.
Queste fasi sono generali e possono essere applicabili a una vasta gamma di programmi, ma li useremo come base per il nostro guscio. La nostra shell sarà così semplice che non ci saranno file di configurazione e nessun comando di spegnimento. Quindi, eseguiremo semplicemente la funzione di looping e poi usciremo. Tuttavia, è essenziale ricordare che la durata del programma è più che un semplice ciclo.
Come creare un semplice shell in c?
Creeremo un guscio di base in C che dimostrerà i fondamenti di come funziona. Poiché il suo obiettivo è la dimostrazione piuttosto che la completezza delle caratteristiche o persino l'idoneità per uso casuale, ha una serie di limitazioni, anche
- Tutti i comandi devono essere digitati in una riga.
- Lo spazio bianco deve essere utilizzato per separare gli argomenti.
- Non ci saranno citazioni o sfuggire a spazi bianchi.
- Non ci sono tubazioni o reindirizzazioni.
- Gli unici incorporati sono "cd", "aiuto" e "uscita".
Ora dai un'occhiata a un programma C che sta costruendo un semplice shell.
#includere
#includere
#includere
#includere
#includere
#includere
int komal_cd (char ** args);
int komal_help (char ** args);
int komal_exit (char ** args);
char *build_in_string [] =
"CD",
"aiuto",
"Uscita"
;
int (*build_in_function []) (char **) =
& komal_cd,
& komal_help,
& komal_exit
;
int komal_builtins ()
restituire dimensioneof (build_in_string) / sizeof (char *);
int komal_cd (char ** args)
if (args [1] == null)
fprintf (Stderr, "komal: argomento atteso a" cd "\ n");
altro
if (chdir (args [1]) != 0)
perror ("komal");
Ritorno 1;
int komal_help (char ** args)
int i;
printf ("Questa è una semplice build C di shell di Komal Batool \ n");
printf ("Digita nomi e argomenti del programma e premi Invio.\N");
printf ("I seguenti sono integrati in: \ n");
per (i = 0; i < komal_builtins(); i++)
printf (" %s \ n", build_in_string [i]);
printf ("Usa il comando man per informazioni su altri programmi.\N");
Ritorno 1;
int komal_exit (char ** args)
restituzione 0;
int komal_launch (char ** args)
pid_t pid;
Stato int;
pid = fork ();
if (pid == 0)
if (ExecVP (args [0], args) == -1)
perror ("komal");
exit (exit_failure);
else if (pid < 0)
perror ("komal");
altro
Fare
waitpid (PID e status, wuntraced);
Mentre (!Mogliexited (status) && !Wifsignaled (status));
Ritorno 1;
int komal_execute (char ** args)
int i;
if (args [0] == null)
Ritorno 1;
per (i = 0; i < komal_builtins(); i++)
if (strcmp (args [0], build_in_string [i]) == 0)
return (*build_in_function [i]) (args);
return komal_launch (args);
char *komal_read_line (void)
#ifdef komal_use_std_getline
char *riga = null;
ssize_t bufsize = 0;
if (getline (& line, & bufsize, stdin) == -1)
if (feof (stdin))
usit (exit_success);
altro
Perror ("komal: getline \ n");
exit (exit_failure);
linea di ritorno;
#altro
#define komal_rl_bufsize 1024
int bufsize = komal_rl_bufsize;
int posizione = 0;
char * buffer = malloc (sizeof (char) * bufsize);
int c;
Se (!respingente)
fprintf (stderr, "komal: errore di allocazione \ n");
exit (exit_failure);
mentre (1)
c = getChar ();
if (c == eof)
usit (exit_success);
else if (c == '\ n')
buffer [posizione] = '\ 0';
tampone di ritorno;
altro
tampone [posizione] = c;
posizione ++;
if (posizione> = bufsize)
bufsize += komal_rl_bufsize;
buffer = realloc (buffer, bufsize);
Se (!respingente)
fprintf (stderr, "komal: errore di allocazione \ n");
exit (exit_failure);
#finisci se
#define komal_tok_bufsize 64
#define komal_tok_delim "\ t \ r \ n \ a"
char ** komal_split_line (char *riga)
int bufsize = komal_tok_bufsize, position = 0;
char ** token = malloc (bufsize *sizeof (char *));
char *token, ** tokens_backup;
Se (!token)
fprintf (stderr, "komal: errore di allocazione \ n");
exit (exit_failure);
token = strtok (riga, komal_tok_delim);
mentre (token != Null)
token [posizione] = token;
posizione ++;
if (posizione> = bufsize)
bufsize += komal_tok_bufsize;
tokens_backup = token;
token = realloc (token, bufsize * sizeof (char *));
Se (!token)
gratuito (tokens_backup);
fprintf (stderr, "komal: errore di allocazione \ n");
exit (exit_failure);
token = strtok (null, komal_tok_delim);
token [posizione] = null;
TOKEN di ritorno;
void komal_loop (void)
char *line;
char ** args;
Stato int;
Fare
printf (">");
riga = komal_read_line ();
args = komal_split_line (riga);
status = komal_execute (args);
linea libera);
libero (args);
while (status);
int main (int argc, char ** argv)
komal_loop ();
restituire exit_success;
Descrizione del codice
Il codice sopra è una semplice implementazione di una shell di comando scritta in c. Il guscio è chiamato "Komal", e può eseguire comandi integrati come "CD", "aiuto" e "uscita", nonché comandi esterni. La funzione principale del programma è il "Komal_loop" funzione, che si diffonde continuamente, leggendo l'input dall'utente tramite il "Komal_read_line" funzione, dividendo l'input in singoli argomenti usando il "Komal_split_line" funzione ed eseguire il comando usando il "Komal_execute" funzione.
IL "Komal_execute" La funzione controlla se il comando è un comando incorporato e, in tal caso, esegue la funzione integrata corrispondente. Se il comando non è un comando incorporato, esegue un comando esterno arendo un processo di figlio e chiamando il "Execvp" Chiamata di sistema per sostituire lo spazio di memoria del processo figlio con il programma desiderato.
IL "Komal_cd", "komal_help", E "Komal_exit" Le funzioni sono le tre funzioni integrate che possono essere eseguite dall'utente. "Komal_cd" Modifica la directory di lavoro corrente, "Komal_help" fornisce informazioni sulla shell e sui suoi comandi integrati e "Komal_exit" esce dal guscio.
Produzione
Conclusione
Costruire una semplice shell in C implica la comprensione di come analizzare ed eseguire comandi, gestire l'input e l'output dell'utente e gestire i processi utilizzando chiamate di sistema come fork e EXECVP. Il processo di creazione di una shell richiede una profonda comprensione del linguaggio di programmazione C e del sistema operativo UNIX. Tuttavia, con l'aiuto dei passaggi e l'esempio fornito nella guida sopra, è possibile creare una shell di base in grado di gestire l'input dell'utente ed eseguire i comandi.