This repository contains the files to simulate a basic Unix Shell with its respective commands. It uses the POSIX API
to implement many of the same functionalities of the first Ken Thompson's Shell.
In C
language, header files (.h
) contain a set of predefined standard library functions. The .h
is the extension of the header files in C
and we request to use a header file in our program by including it with the C preprocessing directive #include <file_name.h>
. C
language has numerous libraries that include predefined functions to make programming easier. The predominantly used system and function calls used in this program are read
, write
, open
, execve
, exit
, fflush
, fork
, free
, malloc
, getline
, isatty
, perror
, strtok
, wait
, and waitpid
.
This simple shell is a Shell interface written in the C
programming language that gives to the user a prompt $
and executes a user-inputted command. The shell is used directly to interact with the Kernel that hosts the OS.
- This program displays a prompt and waits for the user to type a command. A command line always ends with a new line (when the user pushes the ENTER key).
- The prompt is displayed again each time a command has been executed.
- When the user enters exit, the shell will end and returns the status 0.
- The user could stop the program using Ctrl+D (end of file).
- The shell handles the command lines with arguments and pathways.
- The program does not quit when the user inputs ^C (Ctrl+C).
- This program executes the most common shell commands as
ls
,grep
,find
,pwd
,rm
,cp
,mv
,exit
, etc... with arguments. - If an executable cannot be found, it prints an error message and displays the prompt again.
- This Shell does not support commentaries using
#
. - This shell does not support pipes
|
, shell logical operators such as&&
or||
, neither commands separator;
.
-
Operating System: Ubuntu 14.04 LTS
-
Compiler: GCC 4.8.4
The next steps are a brief description of how the shell works:
- First, the parent process is created when the user runs the program.
- Then, the
isatty()
function using theSTDIN_FILENO
file descriptor -fd
- tests if there is an open file descriptor referring to a terminal. Ifisatty()
returns 1, the prompt is shown usingwrite()
withSTDOUT_FILENO
asfd
and waits for input from the user on the command line. - When the user types a command, the
getline()
function reads an entire line from the input stream, andstrtok()
function breaks the inputted command into a sequence of non-empty tokens. - Next, it creates a separate child process using
fork()
that performs the inputted command. Unless otherwise specified, the parent process waits for the child to exit before continuing. - After tokenizing the command,
execve()
executes it, and all allocated memory is freed usingfree()
. - Finally, the program returns to
main()
, prints the prompt, and waits for another user input.
To run this shell with its respective commands, clone this repository in your terminal.
- HTTPS:
git clone https://github.com/richie-omondi/simple_shell.git
- SSH:
git clone [email protected]:richie-omondi/simple_shell.git
gcc -Wall -Wextra -Werror -pedantic -ggdb3 *.c -o hsh
- If you want to debug the shell, use valgrind:
valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all -s ./hsh
More info on Valgrind can be found here: https://valgrind.org/
- Or just run and try this shell using:
./hsh
Here are shown some examples of the usage of the Shell:
- ls
($) ls
add_shell_data.c debugging.txt errors.c free.c memory_functions.c print.c shell.c string_functions_2.c Tasks.md tokenize.c
AUTHORS env.c execute_shell.c hsh Notes.md README.md shell.h string_functions.c test_ls_2
($) /bin/ls
add_shell_data.c debugging.txt errors.c free.c memory_functions.c print.c shell.c string_functions_2.c Tasks.md tokenize.c
AUTHORS env.c execute_shell.c hsh Notes.md README.md shell.h string_functions.c test_ls_2
($) ls -lat
total 108
-rwxr-xr-x 1 root root 23184 Aug 20 07:06 hsh
drwxr-xr-x 3 root root 4096 Aug 20 07:06 .
drwxr-xr-x 8 root root 220 Aug 20 07:06 .git
-rw-r--r-- 1 root root 3957 Aug 20 07:06 README.md
-rw-r--r-- 1 root root 2051 Aug 13 14:20 shell.h
-rw-r--r-- 1 root root 2727 Aug 13 14:20 shell.c
-rw-r--r-- 1 root root 1252 Aug 13 14:16 free.c
-rw-r--r-- 1 root root 2955 Aug 13 07:45 tokenize.c
drwxr-xr-x 1 root root 170 Aug 12 13:49 ..
-rw-r--r-- 1 root root 1667 Aug 9 06:20 string_functions_2.c
-rw-r--r-- 1 root root 16 Aug 9 06:20 test_ls_2
-rw-r--r-- 1 root root 773 Aug 9 06:20 add_shell_data.c
-rw-r--r-- 1 root root 81 Aug 9 06:20 AUTHORS
-rw-r--r-- 1 root root 79 Aug 9 06:20 debugging.txt
-rw-r--r-- 1 root root 957 Aug 9 06:20 env.c
-rw-r--r-- 1 root root 951 Aug 9 06:20 errors.c
-rw-r--r-- 1 root root 862 Aug 9 06:20 execute_shell.c
-rw-r--r-- 1 root root 636 Aug 9 06:20 memory_functions.c
-rw-r--r-- 1 root root 8624 Aug 9 06:20 Notes.md
-rw-r--r-- 1 root root 272 Aug 9 06:20 print.c
-rw-r--r-- 1 root root 2224 Aug 9 06:20 string_functions.c
-rw-r--r-- 1 root root 1574 Aug 9 06:20 Tasks.md
- pwd
($) pwd
/simple_shell
- echo
($) echo Hello World
Hello World
- Ctrl+D and Ctrl+C
($) ^C
($)
vagrant@vagrant-ubuntu-trusty-64:~/ALX/simple_shell$
Note that in the second line the Ctrl+D is typed
- Richard Orido - @richie-omondi
- Maxmillan Rutto - @Maxrutto