A minimal Unix-like command shell implemented in C.
- Built-in commands:
exit,cd,env,setenv,unsetenv,alias,path,man🔧 - Alias support with expansion and automatic alias creation for successfully executed external commands ✨
- Command sequencing (
;), conditionals (&&,||), parallel execution (&) and output redirection (>) 🔗 - Interactive mode (prompt) and batch mode (run commands from a file, return last command's status) 📝
- Signal handling: interactive shell ignores Ctrl+C (SIGINT) while child processes get default behavior; Ctrl+D (EOF) exits the shell 📵
- Manual included (specialized man description) 📓
- Error handling 🪄 + White Space handling
- POSIX-like environment (Linux, macOS) or compatible toolchain
- GCC or Clang
- make (optional)
* Student Name-------------------------- Id
- Astawus Amsalu ------------------ NaScR/1352/16
- ABREHAM ENGIDA ------------------ NaScR/1142/16
- MESERET TAKELE ------------------ NaScR/2919/16
- HAWI KEBEDE --------------------- NaScR/2345/16
- BESUFIKAD TILAHUN --------------- NaScR/1499/16
From the project root:
make
# or compile manually
gcc -std=c11 -Wall -Wextra -o oshell code/*.c
#better to compile with make useing provided MakefileInteractive:
./oshell
$ # prompt appearsBatch (run commands from a file):
./oshell myscript.sh
# No prompt is printed; the program exits with the last command's exit status- Create or update an alias:
alias ll='ls -l'- List aliases:
alias # prints all
alias ll # prints the `ll` alias- Alias expansion details:
- Alias values may be quoted with single or double quotes.
- Only the first token is expanded and any remaining arguments are appended to the expanded command.
- Recursive expansions are limited to 10 levels to avoid infinite loops.
- Automatic alias creation: when an external command is executed successfully, OShell creates an alias mapping the command name to the resolved full path (e.g.,
ls→/bin/ls) if not already present.
Note: There is no unalias builtin yet; you can overwrite an alias by re-defining it.
- Ctrl+C (SIGINT): ignored by the interactive shell itself (so it won't exit the shell). Child processes restore default SIGINT and therefore can be interrupted.
- Ctrl+D (EOF): ends interactive session and exits the shell gracefully.
-
Builtins affecting shell process:
cd /tmpthenpwdshould show/tmp.setenv TEST yesthenenv | grep TESTshould showTEST=yes.exit 5should exit the shell with code 5 (for batch files, check return value).
-
Aliases:
alias ll='ls -l'→ll /tmpshould list/tmpin long format.- Run
lsand thenalias lsshould show a mapping to the resolved path.
-
Redirection and builtin interaction:
echo hi > out.txtcreatesout.txtand the shell should continue to print normally after.
-
Signals:
- Start a long-running command:
sleep 10and press Ctrl+C to interrupt the child but remain in shell. - Press Ctrl+D at the prompt to exit.
- Start a long-running command:
- Key sources:
code/main.c— entrypoint and interactive/batch handlingcode/parser.c— tokenization, parsing, execution, redirection, and conditionalscode/builtin.c,code/builtin.h— builtins and alias storagecode/main.c- shell entry pointMakefile- easy compilation
parser.hexportsparse_line()which now returns an integer exit status for use in batch files.- Aliases are stored in an in-memory table; persistence and
unaliascan be added later.
-
Builtins affecting shell process:
cd /tmpthenpwdshows/tmp.setenv TEST yesthenenv | grep TESTshowsTEST=yes.exit 5exits the shell with code 5 (for batch files, check return value).
-
Aliases:
alias ll='ls -l'→ll /tmplists/tmpin long format.- Run
lsand thenalias lsshows a mapping to the resolved path.
-
Redirection and builtin interaction:
echo hi > out.txtcreatesout.txtand the shell continue to print normally after.
-
Signals:
- Start a long-running command:
sleep 10and press Ctrl+C to interrupt the child but remain in shell. - Press Ctrl+D at the prompt to exit.
- Start a long-running command:
- Open an issue or create a pull request for features