This is a simple shell-like command interpreter. It supports basic operations like executing programs (using execvp internally) and changing directories with cd (using chdir). Implementation of additional features is planned.
This shell is not POSIX-compliant and does not have any scripting capabilities. That's mainly because it does not have a complex parser. Instead, single lines are read from stdin and split at delimiters like or tabs. Only a limited set of special characters like | are treated differently.
GNU shell documentation that covers the basic features of bash can be found here. Implementing some of these features might be educational, too.
- implement two-way pipes with
|(pipesystem call) - implement file IO redirection with
>(openinstead ofpipes) - implement
setenvin child process, i.e. in cmds likeVAR=val echo $VARprintsval - implement shell variable expansion via
getenv(likeecho $HOMEprints/home/daniel) - implement background processes with
&(don't wait on child process)
- implement arbitrary-length pipes
- implement redirection of fd 2 (
stderrlikeecho 'err' 2> out) - implement redirection of fd 2 to fd 1 (like
echo 'err' > out 2>&1) - implement
exportbuiltin which sets a var in the parent - implement wildcard expansion (look at
globinglob.h) - implement aliasing of commands
- support a settings file:
- aliases
- exported variables
-
$PS1
Pipes:
int pipe_fds[2];
pipe(pipe_fds); // puts returns [4, 5] in pipe_fds
To create a pipe ls | wc, we need to:
- create a pipe with
pipe. Imagine that this creates file descriptors4and5. - fork twice (once for
lsand once forwc).
parent: pid 1000, stdin: terminal, stdout, terminal
---- fork twice ----
parent: pid 1000, stdin: terminal, stdout: terminal
child 1: pid 2000, stdin: terminal, stdout: terminal (for `ls`)
child 2: pid 3000, stdin: terminal, stdout: terminal (for `wc`)
- In child 1, run
dup2(pipe_fds[1], 1)and execls - In child 2, run
dup2(pipe_fds[0], 0)and execwc - Close both ends of the pipe in the parent process.
-
Write a
fork_and_exec_with_io(cmd* cmd, int stdout_fd, int stdin_fd)that forks and execs the specified command and changes its stdin and stdout as needed -
Use
fork_and_exec_with_ioto implement pipes with 2 elements.
All code in this repository is MIT-licensed (see license file).