About β’ Important Information β’ Utilities β’ Command Examples β’ Norminette β’ Contributing β’ License
The existence of shells is linked to the very existence of IT. At the time, all developers agreed that communicating with a computer using aligned 1/0 switches was seriously irritating. It was only logical that they came up with the idea of creating software to communicate with a computer using interactive lines of commands in a language somewhat close to the human language.
Thanks to Minishell, I travelled through time and came back to problems people faced when Windows didnβt exist. This project was about creating a simple shell, my own little bash. I learned a lot about processes and file descriptors.
- Subject
PDF
- References
GitHub
Check this list before delivering the project.
- Check the norminette for any errors.
- Check for segmentation faults, bus errors, double free, leaks, ...
- Must compile with -Wall, -Wextra and -Werror.
- Makefile must contain $(NAME), all, clean, fclean.
- Check for forbidden functions in your code.
- Check the subject for any other requirements.
Some nice-to-know commands that will help the evaluatee and the evaluator.
Important Commands | Description |
---|---|
make -n |
Display the compilation information without actually compiling the code. |
echo $? |
Display the exit status of the last executed command. |
nm -g ./minishell | grep " U " |
Check for forbidden functions. |
norminette |
Checks the code for compliance with the coding style and guidelines. |
-R CheckForbiddenSourceHeader |
Check the code in header files. |
cc -g -Wall -Wextra -Werror |
Compile with the mandatory flags. |
-fsanitize=address |
Check for leaks. |
-lreadline |
Necessary to use the readline library. |
ps -e or ps -A |
See all processes currently running on your computer. |
ps -a |
Check for any dead children. |
Important valgrind flags that are necessary to know every single leak.
Valgrind Flags | Description |
---|---|
valgrind ./minishell |
Check for leaks |
-leak-check=full |
Detailed checking for memory leaks. |
--show-leak-kinds=all |
Display all types of memory leaks. |
--track-origins=yes |
Tracks the origins of uninitialized values. |
--verbose |
Increases the level of verbosity. |
--gen-suppressions=all |
Ignore specific known issues or false positives. |
--suppressions=readline.supp |
Specifies the path to a suppression file. |
--log-file=memleaks.log |
Sets the name of the file. |
To ignore leaks related to the
readline
andadd_history
functions, create a file calledreadline.supp
with the following content:
{
leak readline
Memcheck:Leak
...
fun:readline
}
{
leak add_history
Memcheck:Leak
...
fun:add_history
}
valgrind --suppressions=readline.supp --leak-check=full --show-leak-kinds=all ./minishell
The values that a function returns when it completes.
- All Linux commands return an error code between
0
and255
. - The value 0 represents the value true (command success).
- Values greater than 0 represent false (command failure).
- The error code of the last command used is contained in the variable
$?
.
$? | Description |
---|---|
1 |
Standard for general errors, such as a division by zero. |
2 |
Improper use of built-in commands, per Bash documentation. |
126 |
The command called cannot be executed, rights problem or the command is not executable. |
127 |
Command not found, possible problem with $PATH or typing error. |
128 |
Invalid command argument. |
128+n |
128 + signal number. |
130 |
Finished with Ctrl + C (130 = 128 + 2). |
255 |
Exit code out of bounds. Example: exit -1 . |
More nice-to-know commands that may be useful in the future.
Command | Description |
---|---|
yes |
Writes in an infinite loop yes teste . |
ln |
Bind a file or directory. |
chmod |
Change file permissions chmod 777 (all permissions) chmod 000 (no permissions). |
cd |
Change directory. cd - (last visited directory) cd (user directory) cd / (root). |
clear |
Clear the screen. |
diff |
Compare files line by line. |
cmp |
Write the first line of difference between 2 files. |
pc |
Copying files. |
rm |
Delete file. |
rm -rf |
Delete the directory recursively. |
ls -l |
Show the contents of the directory. |
exit |
Exit current process. |
grep |
Search for strings in files grep "printf" file . |
mkdir |
Create a directory. |
rmdir |
Delete a directory. |
more |
Displays a file page by page as in a man. |
mv |
Move or rename. |
$PATH |
Path to executables. |
cat |
Send the file to stdout. |
Change the access permissions and the special mode flags of file system objects.
Rights | Number |
---|---|
r (read) |
4 |
w (write) |
2 |
x (execute) |
1 |
Rights | Calculation | Total |
---|---|---|
--- |
0+0+0 |
0 |
r-- |
4+0+0 |
4 |
-w- |
0+2+0 |
2 |
--x |
0+0+1 |
1 |
rw- |
4+2+0 |
6 |
-wx |
0+2+1 |
3 |
x-ray |
4+0+1 |
5 |
rwx |
4+2+1 |
7 |
All data types, their size in bytes and the INT MIN and INT MAX range.
Data Types | Qualifiers | Size (in byte) | Range |
---|---|---|---|
char |
char or signed char |
1 |
-128 to 127 |
char |
unsigned char |
1 |
0 to 255 |
int |
int or signed int |
4 |
-2147483648 to 2147483647 |
int |
unsigned int |
4 |
0 to 4294967295 |
int |
short int or short signed int |
2 |
-32768 to 32767 |
int |
unsigned short int |
2 |
0 to 65535 |
int |
long int or signed long int |
4 |
-2147483648 to 2147483647 |
int |
unsigned long int |
4 |
0 to 4294967295 |
float |
float |
4 |
1.1754e-38 to 3.4028e+38 |
float |
double |
8 |
2.2250e-308 to 1.7976e+308 |
float |
long double |
10 |
3.4E-4932 to 3.4E+4932 |
Some example commands that can be tested on minishell or break it.
Status | Definition |
---|---|
π’ | Working. |
π‘ | Didn't test yet. |
π£ | Leaks or segmentation fault. |
βͺ | Weird behaviour. |
π΄ | Not working. |
π΅ | Not mandatory. |
Exploring fundamental commands in Minishell, unravelling the core of shell interactions.
Status | Command |
---|---|
π’ | <empty> |
π’ | <spaces> |
π’ | ../../ |
π’ | $ |
Understanding system signals, showcasing the shell's adaptability in various scenarios.
Status | Command |
---|---|
π’ | Ctrl + C |
π’ | Ctrl + D |
π’ | Ctrl + \ |
π’ | write something then press + Ctrl + C |
π’ | write something then press + Ctrl + D |
π’ | write something then press + Ctrl + \ |
π’ | cat + Ctrl + C |
π’ | cat + Ctrl + D |
π’ | cat + Ctrl + \ |
π’ | sleep 5 + Ctrl + C |
π’ | sleep 5 + Ctrl + D |
π’ | sleep 5 + Ctrl + \ |
Managing executable file access by manipulating the system path in Minishell.
Status | Command |
---|---|
π’ | /bin/echo |
π’ | /bin/grep |
π’ | /bin/ls |
π’ | /bin/ls -la |
π’ | /bin/cat |
π’ | /bin/pwd |
π’ | /bin/cd |
π’ | /bin/export |
π’ | /bin/env |
π’ | /bin/exit |
Locating the present directory through the pwd command in Minishell.
Status | Command |
---|---|
π’ | pwd |
π’ | pwd a |
π’ | pwd a b c d |
Harnessing environment variables via export, env, and unset commands in Minishell.
Status | Command |
---|---|
π’ | ENV |
π’ | eNv |
π’ | env |
π’ | env |
π’ | env |
π’ | env |
π’ | UNSET |
π’ | uNsEt |
π’ | unset |
π’ | unset |
π’ | unset |
π’ | unset |
π’ | unset [variable] |
π’ | unset [variable] [variable] |
π’ | unset [all variables] |
π’ | EXPORT |
π’ | eXpOrT |
π’ | export |
π’ | export |
π’ | export |
π’ | export |
π’ | export a=42 |
π’ | export a=24 |
π’ | export b=42 |
π’ | export a = 42 |
π’ | export a=" 42 " |
π’ | export a=' 42 ' |
π’ | export a = 42 |
π’ | export a |
π’ | export a='' |
π’ | export a='"' |
π’ | export a='\' |
π’ | export a='$' |
π’ | export a='\t' |
π’ | export a=''' |
π’ | export = |
π’ | export == |
π’ | export a= |
π’ | export a=42= |
π’ | export =a=42 |
π’ | export a==42 |
π’ | export "a=42" |
π’ | export a="42" |
π’ | export _=42 |
π’ | export 42=42 |
π’ | export a b = 42 |
π’ | export a= b= 42 |
π’ | export a=42 % b=42 @ c=42 |
π’ | export a=42 b=42 c=42 |
π’ | export A=a B=b C=c D=d E=e |
π’ | export F=f G=g H=h I=i J=j |
π’ | export K=k L=l M=m N=n O=o |
π’ | export P=p Q=q R=r S=s T=t |
π’ | export U=u V=v W=w X=x Y=y Z=z |
π’ | export _=a; echo $_a |
Concluding Minishell's operations gracefully using the exit command.
Status | Command |
---|---|
π’ | EXIT |
π’ | eXiT |
π’ | exit |
π’ | exit |
π’ | exit |
π’ | exit |
π’ | exit test |
π’ | exit "test" |
π’ | "exit test" |
π’ | "exit" |
π’ | exit1 |
π’ | exita |
π’ | exit exit |
π’ | exit a |
π’ | exit abc |
π’ | exit a b c |
π’ | exit a b c d |
π’ | exit # |
π’ | exit * |
π’ | exit 0 |
π’ | exit 1 |
π’ | exit 123 |
π’ | exit 1234 |
π’ | exit 1 2 3 4 |
π’ | exit + |
π’ | exit - |
π’ | exit +10 |
π’ | exit -10 |
π’ | exit +2000 |
π’ | exit -2000 |
π’ | exit +-2000 |
π’ | exit -+2000 |
π’ | exit ++2000 |
π’ | exit --2000 |
π’ | exit -2147483649 |
π’ | exit 2147483648 |
π’ | exit 00000000000000000000 |
π’ | exit 11111111111111111111 |
π’ | exit'42' |
π’ | exit '\t42' |
π’ | exit '\t\f\r 42' |
π’ | exit '42 ' |
π’ | exit '42\t' |
π’ | exit '42\r' |
π’ | exit '42\t\f\r ' |
π’ | exit '42 a' |
π’ | exit '42\t\t\ta' |
Traversing directories seamlessly using the cd command in Minishell.
Status | Command |
---|---|
π’ | CD |
π’ | cd |
π’ | cd |
π’ | cd |
π’ | cd |
π’ | cd . |
π’ | cd ~ |
π’ | cd no_file |
π’ | cd1 |
π’ | cd 0 |
π’ | cd 1 |
π’ | cd 123 |
π’ | cd 1234 |
π’ | cd 1 2 3 4 |
π’ | cd cd |
π’ | cd a |
π’ | cd abc |
π’ | cd a b c |
π’ | cd a b c d |
π’ | cd ../../ |
π’ | cd ../../../../../../ |
π’ | cd ../../... |
π’ | cd .../../.. |
π’ | cd .../../... |
π’ | cd \ |
π’ | cd / |
π’ | cd // |
π’ | cd /// |
π’ | cd - |
π’ | cd $[VAR] |
Rendering text and variables in the terminal with the versatile echo command in Minishell.
Status | Command |
---|---|
π’ | ECHO |
π’ | echO |
π’ | ECHo |
π’ | echo |
π’ | echo echo |
π’ | echo |
π’ | echo |
π’ | echo |
π’ | echo . |
π’ | echo ~ |
π’ | echo echo ~ |
π’ | "echo test" |
π’ | echo "~" |
π’ | echo '~' |
π’ | echo ~123 |
π’ | echo 123~ |
π’ | echo ~/123 |
π’ | echo ~/123/456 |
π’ | echo # |
π’ | echofile |
π’ | echo file |
π’ | echo no_file |
π’ | echo file test |
π’ | echo file test |
π’ | echo file test file test |
π’ | echo a"b"c |
π’ | echo "a'b'c |
π’ | echo "test" |
π’ | echo test |
π’ | echo 'test' |
π’ | echo -n |
π’ | echo -n -n -n -n |
π’ | echo -nnnnnnnnnnnnnnnnnnnnnnnn |
π’ | echo -n test -n |
π’ | "echo" "-n" |
π’ | echo -n test |
π’ | echo -nn test |
π’ | echo -n -n -n test |
π’ | echo "-n" test |
π’ | echo -n"-n" test |
π’ | echo "-nnnn" test |
π’ | echo "-n -n -n"-n test |
π’ | echo "-n '-n'" test |
π’ | echo -n file test |
π’ | echo -n -n -n file test |
π’ | echo $USER |
π’ | echo "$USER" |
π’ | echo "'$USER'" |
π’ | echo " '$USER' " |
π’ | echo text"$USER" |
π’ | echo text"'$USER'" ' $USER ' |
π’ | echo "text" "$USER" "$USER" |
π’ | echo ' $USER ' |
π’ | echo text "$USER" "$USER"text |
π’ | echo ''''''''''$USER'''''''''' |
π’ | echo """"""""$USER"""""""" |
π’ | echo $USER'$USER'text oui oui oui oui $USER oui $USER '' |
π’ | echo $USER '' $USER $USER '' $USER '' $USER -n $USER |
π’ | echo ' \' ' \' |
π’ | echo '\" ' " \"\"" |
π’ | echo \\\" \\\" \\\" \\\"\\\"\\\" \\\'\\\'\\\' |
π’ | echo "$USER""$USER""$USER" |
π’ | echo text"$USER"test |
π’ | echo '$USER' "$USER" "text \' text" |
π’ | echo '$USER' |
π’ | echo $USER " " |
π’ | echo "$USER""Users/$USER/file""'$USER'"'$USER' |
π’ | echo "$USER$USER$USER" |
π’ | echo '$USER'"$USER"'$USER' |
π’ | echo '"$USER"''$USER'"""$USER" |
π’ | echo " $USER "'$PWD' |
π’ | echo " $USER \$ "'$PWD' |
π’ | echo $USER=4 |
π’ | echo $USER=thallard |
π’ | echo $USER |
π’ | echo $? |
π’ | echo $USER213 |
π’ | echo $USER$12USER$USER=4$USER12 |
π’ | echo $USER $123456789USER $USER123456789 |
π’ | echo $USER $9999USER $8888USER $7777USER |
π’ | echo $USER $USER9999 $USER8888 $USER7777 |
π’ | echo $USER $USER9999 $USER8888 $USER7777 "$USER" |
π’ | echo "$USER=12$USER" |
π’ | echo "$9USER" "'$USER=12$SOMETHING'" |
π’ | echo $PWD/file |
π’ | echo "$PWD/file |
π’ | echo "text" "text$USER" ... "$USER |
π’ | echo $PW |
π’ | echo "'"'ola'"'" |
π’ | echo "'"' ola '"'" |
At 42 School, it is expected that almost every project is written following the Norm, which is the coding standard of the school.
- No for, do...while, switch, case, goto, ternary operators, or variable-length arrays allowed;
- Each function must be a maximum of 25 lines, not counting the function's curly brackets;
- Each line must be at most 80 columns wide, with comments included;
- A function can take 4 named parameters maximum;
- No assigns and declarations in the same line (unless static);
- You can't declare more than 5 variables per function;
- ...
- 42 Norms - Information about 42 code norms.
PDF
- Norminette - Tool to respect the code norm, made by 42.
GitHub
- 42 Header - 42 header for Vim.
GitHub
If you find any issues or have suggestions for improvements, feel free to fork the repository and open an issue or submit a pull request.
This project is available under the MIT License. For further details, please refer to the LICENSE file.