The 21sh project is an extension of the Minishell project. It involves building upon the basic shell created in Minishell to develop a more functional and feature-rich shell. The key features that you will add to your shell include:
-
Multi-command management: This feature enables handling multiple commands in a single line, separated by semicolons or logical operators (e.g.,
ls -l; echo hello
). -
Redirections: This feature allows for the redirection of input and output to/from files using operators such as '<', '>', and '>>'.
-
Line edition: With the termcaps library, you can add a line edition feature to your shell. This feature lets you edit a typo in a command without having to retype the entire command. It also allows for the repetition of previous commands using history.
-
Interprocess communication using pipes: The pipe system call enables communication between processes. This feature allows you to chain commands together and redirect their output to the input of another command.
-
Syntax and grammar analysis: Your shell will implement lexical, syntactic, and semantic analysis to understand and execute the commands that the user inputs. This involves using techniques such as lexical analysis, lexer, syntactic analysis, parser, semantic analysis, interpreter, and abstract syntax tree (AST).
-
Code organization: It's crucial to maintain clear and well-managed code organization to save time and avoid a simple space-based split on your command line.
-
Error handling: Your program should handle errors carefully. It should not quit unexpectedly (e.g., Segmentation fault, bus error, double free, etc.).
-
Memory management: Your program should not have any memory leaks.
To compile and run this program you will need:
- A Unix or Unix-like operating system (preferrably MacOs or Linux)
- GNU Make 3.81
Clone the repository to your local machine
git clone https://github.com/maxrantil/21sh.git
Navigate to the 21sh directory
cd 21sh
Compile the program
make
Run the shell
./21sh
- Operators:
; | >> > << < >& <&
- Line edition using the termcaps library.
- History of commands using up and down arrows
- Movement in line with left and right arrows.
- Movement word by word with alt + left and right arrows.
- Movement one line up and down with alt + up and down arrows.
- ctrl+U to copy line, ctrl+W to cut line, ctrl+Y to paste line in the app.
- Copy/paste functionality from outside of the app with the standard key combinations.
- Home and end keys to go to the beginning and end of the command.
- Line editing over multiple lines.
- Built-ins:
- echo (no options, checks that the fd is valid).
- env with options.
- cd with absolute and relative paths, options:
cd -, cd ~
- setenv and unsetenv to set environment variables in the format 'key value'
- exit
- ctrl+D, ctrl+C signal handling.
- Complete management of quotes (single quotes, double quotes, and backslash)
- No leaks, no extra file descriptors, error handling done manually without errno.
- Allowed C-library functions in this project:
- malloc, free
- access
- open, close, read, write
- opendir, readdir, closedir
- getcwd, chdir
- stat, lstat, fstat
- fork, execve
- wait, waitpid, wait3, wait4
- signal, kill
- exit -pipe
- dup, dup2
- isatty, ttyname, ttyslot
- ioctl
- getenv
- tcsetattr, tcgetattr
- tgetent, tgetflag, tgetnum, tgetstr
- tgoto, tputs
An abstract syntax tree (AST) is a tree representation of the abstract syntactic structure of source code written in a programming language. Understanding how to construct and navigate an AST is an important skill for language interpreters and compilers. Lexical analysis, also known as lexing or tokenization, is the process of converting a stream of text into a sequence of tokens, which are the basic building blocks of a programming language. By learning about abstract-syntax-trees and lexical analysis, I gained a deeper understanding of how interpreters and compilers work, and how they process and understand code.
C is a low-level programming language that provides a lot of flexibility and control over memory management. By deepening my knowledge of complex data structures in C, I gained a better understanding of how to use data structures like linked lists and trees, as well as how to optimize memory usage.
Command-line operations and shell-scripting are powerful tools for automating and managing tasks on a Unix operating system. By gaining a more nuanced understanding of these tools, I became more proficient at using them to automate repetitive tasks, perform complex operations on the command-line, and write scripts to manage your system.
A file descriptor is an integer value that is used to refer to an open file or other input/output resource in Unix operating systems. Understanding how to use file descriptors is an important skill for working with files and other resources on a Unix system. By improving my working knowledge of Unix operating systems, I gained a better understanding of how to use file descriptors, as well as how to manage processes on a Unix system.
Working on long-term projects with other developers requires strong planning and project management skills. By improving my skills in these areas, I became more effective at organizing tasks, delegating responsibilities, and communicating with team members to ensure that projects are completed on time and to the desired quality.