Mini shell written in C for an Operating Systems course. The constraint was to use only POSIX system calls — no
system(), and no shelling out to top/ps/uptime for the monitoring features.
It supports three things:
- running a command with output or input redirection (
>,<) - piping the output of one command into another (
|) - a
topmode that prints CPU load average and the number of running processes, read directly from/proc
Linux only — it depends on /proc and POSIX APIs. On Windows it runs fine under WSL.
gcc -Wall -Wextra -O2 -o mycmd myCMD.c
Usage
./mycmd ls -la
./mycmd ls -la > out.txt
./mycmd wc -l < in.txt
./mycmd ls -la | grep ".c"
./mycmd top
In top mode the screen refreshes every 10 seconds. Press q then Enter to quit.How it works
Everything is in a single file (myCMD.c). The main pieces:
- parse() — walks through argv looking for >, < or | and splits the arguments into "first command" and "second command".
- executarComandos() — fork + execvp. For pipes, it sets up the pipe with pipe() and uses dup2 to wire the child's stdout into the parent's stdin before running the second command.
- executarComandosComRedirecionamentoOutput / Input() — opens the target file with open() and uses dup2 to swap STDOUT_FILENO or STDIN_FILENO before execvp.
- mostrarCargaMediaCPU() — reads /proc/loadavg.
- mostrarStatusProcessos() — opens /proc, treats numeric directory names as PIDs, and parses /proc//stat to count processes in state R.
- lmparMemoria() — frees the buffers allocated during parsing.
Project layout
. ├── myCMD.c └── README.md
Limitations
- Only one operator per invocation. No chained pipes, and you can't mix a pipe with redirection in the same command.
- Source comments are in Portuguese (kept as submitted).
- There's a typo in one function name (lmparMemoria instead of limparMemoria) — left as-is to keep the code in its original state.