back to scratko.xyz
aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 7f30423ce71532925aa0f8663d6b25d42f7a1eb1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# Simple UNIX Shell

A lightweight command-line shell implemented in C, designed to emulate core
functionalities of UNIX shells like `sh` or `bash`. This shell supports
**process management**, **I/O redirection**, **pipelining (|)**, **subshells**,
**logical operators (&&, ||)**, **interactive input handling including
autocompletion** and **basic signal handling**. The implementation demonstrates
system-level programming concepts using **POSIX APIs**.

<img src="shell_1.png" />

<img src="shell_2.png" />

---

## Features

-  **Command Execution**   
Executes external programs using `fork()` and `execvp()`, with environment lookup
via `$PATH`.

-  **Foreground and background job execution**  
Commands can be run in the background by appending `&`.

-  **Redirection**  
Input/output redirection using `<`, `>`, and `>>`. _Examples:_
    - `cat < input.txt`
    - `ls > out.txt`
    - `echo foo >> log.txt`

-  **Quoting and escape sequences**  
Basic support for `"quoted strings"` and escape sequences like `\ ` or `\"`.

- **Logical Operators**  
Implements support for `&&` and `||` operators, enabling conditional command
execution. These operators can be combined with pipelines and subshells.

- **Subshells**  
Commands enclosed in parentheses `()` are executed in subshells,
enabling complex nested logic.

-  **Pipelines**  
Unix-style pipelines using the pipe (|) operator. Data is passed from one
process to another via standard input/output.
_Example: `cat file.txt | grep foo | sort`_

- **Directory Navigation**  
Supports the built-in `cd` command to change the current working directory via
`chdir()`.

- **Autocompletion (Tab)**  
Custom autocompletion implemented using raw terminal input:
    - If the current token is a command: matches against executables in `$PATH`.
    - Otherwise: matches file and directory names from the current or specified path.

- **Interactive Line Editing**  
Terminal is switched to non-canonical mode. Input handling is implemented manually:
    - Character-by-character input display.
    - Left/right arrow keys for cursor movement.
    - `Backspace` support with live line re-rendering.
    - `Ctrl+D` to terminate the shell.
    - `Tab` triggers autocompletion.

-  **Signal handling**  
Handles SIGCHLD to reap zombie processes and prevent defunct children.

---

## Technologies Used

- **Language**: C (C99)
- **System APIs**: POSIX (`fork`, `execvp`, `waitpid`, `pipe`, `dup2`, `tcsetpgrp`, etc.)
- **Memory handling**: dynamic memory allocation (`malloc`, `free`)
- **Terminal control**: `tcgetpgrp`, `tcsetpgrp`, `tcgetattr`, `tcsetattr`

---

## Limitations

While the shell supports many core UNIX behaviors, it has some limitations compared to full-featured shells:

-  No scripting constructs (`if`, `while`, `for`, etc.)
-  No variable expansion (e.g. `$HOME`, `$PATH`, `$?`)
-  No command substitution (e.g. `` `command` `` or `$(command)`)
-  No history (up arrow)
-  No job control (e.g. fg, bg, jobs).
-  No advanced signal features (sigaction, sigprocmask, kill, etc.).

You’ll see a prompt where you can enter commands, use pipes, redirection, and
job control. You can also interact via signals like Ctrl+C and Ctrl+Z.