Skip to content
This repository was archived by the owner on Aug 25, 2026. It is now read-only.
ReeseArch64Public archive

About

Um shell de terminal próprio, escrito em Object Pascal (Free Pascal), implementado do zero por cima das chamadas de sistema POSIX — sem delegar para /bin/sh por trás dos panos. O objetivo é entender e reproduzir, na prática, como um shell de verdade lê um comando e o transforma em processos rodando de fato no sistema operacional.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

my-shell

Um shell de terminal próprio, escrito em Object Pascal (Free Pascal), implementado do zero por cima das chamadas de sistema POSIX — sem delegar para /bin/sh por trás dos panos. O objetivo é entender e reproduzir, na prática, como um shell de verdade lê um comando e o transforma em processos rodando de fato no sistema operacional.

O que ele faz

  • Loop de comandos (REPL): lê uma linha, interpreta, executa, repete.
  • Comandos internos (builtins): cd, pwd, status e help rodam dentro do próprio processo do shell — precisam disso porque mudar de diretório num processo filho não afetaria o pai.
  • Execução de processos externos: qualquer outro comando (ls, grep, cat, o binário que for) é executado via fork + execvp, do jeito que um shell Unix faz de verdade.
  • Redirecionamento de E/S: > (sobrescreve), >> (concatena) e < (lê de arquivo).
  • Pipes: comando1 | comando2 | comando3 encadeia a saída de um processo na entrada do próximo, com quantos estágios forem digitados.
  • Sinais: o shell ignora Ctrl+C (SIGINT) para si mesmo — só o comando em execução recebe o sinal e pode morrer com ele, exatamente como o bash se comporta.
  • Código de saída: o shell guarda o exit code do último comando/pipeline rodado; status mostra esse valor.

Por que Pascal e não C

Pascal foi escolhido pela clareza da sintaxe ao lidar com as mesmas chamadas de baixo nível que um shell em C usaria (fork, execvp, pipe, dup2, waitpid) — o Free Pascal expõe todas elas diretamente através das units BaseUnix e Unix, sem precisar de bindings externos.

Como o comando digitado vira processo

  1. A linha é dividida em estágios de pipeline (separados por |).
  2. Cada estágio é tokenizado (separado por espaço) e tem seus tokens de redirecionamento (<, >, >>) extraídos.
  3. Se a linha inteira for um único estágio e o primeiro token for um builtin (cd, pwd, status, help), ele roda direto no processo do shell.
  4. Caso contrário, o shell dá fork:
    • No processo filho, os descritores de entrada/saída são religados (pipe e/ou arquivo, via dup2) e a imagem do processo é trocada pelo comando pedido, com execvp.
    • No processo pai, o shell espera (waitpid) o(s) filho(s) terminar(em) e guarda o código de saída.

Estrutura

my-shell/
├── src/
│   └── myshell.pas   # todo o shell: tokenizer, redirecionamento, pipes, execução, builtins
├── Makefile          # build via `make`
└── README.md

Compilando e rodando

Requer o Free Pascal Compiler (fpc), versão 3.x, num sistema Unix-like (usa BaseUnix/Unix, específicas de Linux/BSD/macOS).

make        # compila e gera o binário ./myshell
make run    # compila (se preciso) e já abre o shell
make clean  # remove binário e artefatos de compilação

Ou direto, sem Makefile:

fpc -Fusrc src/myshell.pas -o myshell
./myshell

Exemplos de uso

my-shell$ pwd
/home/usuario/my-shell

my-shell$ echo ola > saida.txt
my-shell$ cat saida.txt
ola

my-shell$ echo mais >> saida.txt
my-shell$ cat saida.txt
ola
mais

my-shell$ ls -la | grep .pas | wc -l
1

my-shell$ cat < saida.txt | sort | head -1
mais

my-shell$ cd ..
my-shell$ status
0

my-shell$ exit

Comandos internos

Comando O que faz
cd [dir] Muda o diretório atual (sem argumento, vai para $HOME)
pwd Mostra o diretório atual
status Mostra o código de saída do último comando/pipeline
help Lista os comandos internos disponíveis
exit Encerra o shell

Limitações conhecidas

  • Não interpreta aspas ("...", '...') nem escapes — tokens são separados só por espaço.
  • Não expande variáveis de ambiente ($HOME, $PATH são lidos pelo processo filho via execvp, mas não são expandidos dentro de uma string digitada) nem glob (*.txt).
  • Sem histórico de comandos, autocomplete ou edição de linha além do que o terminal já oferece.
  • Sem controle de job (&, bg, fg, Ctrl+Z) — cada comando roda em primeiro plano.

Essas são fronteiras deliberadas do escopo deste projeto: o foco é entender comandos, pipes, redirecionamento e execução de processos — não reimplementar um shell POSIX completo.

Licença

Este projeto é distribuído sob a licença MIT — veja LICENSE.

About

Um shell de terminal próprio, escrito em Object Pascal (Free Pascal), implementado do zero por cima das chamadas de sistema POSIX — sem delegar para /bin/sh por trás dos panos. O objetivo é entender e reproduzir, na prática, como um shell de verdade lê um comando e o transforma em processos rodando de fato no sistema operacional.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages