Implementing a shell with basic function with ONLY POSIX system call.
- OS version :
OSX 10.15.7+ - C++ version :
c++17 - Compiler :
Apple Clang 13.0.0 - Bison :
GNU Bison 3.2+ - flex :
flex 2.6.4
Note : This shell implement does not fully satisfy POSIX standard. See POSIX shell standard.
Here is a list of default environment variables.
HOME: The path to user's home directoryPWD: Current work directorySHELL: System default shellPATH: Executable file search path. Default to./bin:/bin:/usr/binwhere.will be replaced with launch path, this setting should be able to execute most system executable command such as ps, cat and etc.
Built-in command is command that will executed by shell itself. Currently redirection for such command is disabled.
bg: Move job to background and continue to execute.bg 1means move the first job to background. Note that indexing job with%nwill cause syntax error.cd: Change work directory.cd ~/.vimwill enter~/.vim.echo: Print a string or something.echo $PWDwill print environment variablePWD.exit: Quit shell. This is equivalent to pressctrl+D.fg: Move job to foreground, similar tobg.jobs: List all jobs and each process under the job.set: Print all environment variables.shift: Reserved.test: Reserved.time: Reserved.unmask: Reserved.
This feature is enabled only when shell is interactive.
By default each command is run as an individual process and will take control of terminal while shell is waiting for it to quit. However, by appending & to the end of command, shell will run the process as a background process. A background process will run without controlling terminal and is immune to terminal signals.
Here is a list of signals that possibly be support. Note this is terminal dependent.
ctrl + Cwhich isSIGINT, will terminate process unless handled.ctrl + Dwhich is actually not a signal, will write anEOFtostdin.ctrl + Zwhich isSIGTSTP, will suspend a process unless handled.ctrl + Ysimilar toctrl + Z, but will be sent when process attempt to read from stdin.
Other signal may also be support by your terminal. Checkout GNU's description.
cmd1 arg1 ; cmd2 arg2 arg3will executecmd1and after it finishedcmd2will be executed.cmd1 arg1& cmd2 arg2 &will executecmd1andcmd2concurrently.fg 1will bring the first job to foreground if existed.jobswill print a list of all current jobs.
This two concepts can often cause confusion. Basically, a job is a group of processes that share the same pgid or process group id. This is independent of pid and can be modified after process has been launched while pid can not.
A process can control a terminal if it has the same pgid as the terminal's. By controlling a terminal, a process is able to read input from it and receive signals that is sent to terminal's process group. In such condition, a process is called a Foreground process. Otherwise, it is a Background process. Both kinds of process is able to write output to terminal.
See GNU : Implementing a Job Control Shell for some guidance.
Shell expands some string automatically. See GNU's description
$VARwill be replaced with shell's corresponding variable's content.~will be replaced with$HOME.\is used as escape character. For instance,"\n\006\\"will print newline, ascii\06and a\. Outside string\is also used as escaped character. For example,\>will be interpreted as>."asdf" 'asdf'String is quoted by'""and must be paired unless escaped by\. Otherwise it will cause a syntax error.- Other expansion and expansion in string is not supported concurrently.
Shell support redirecting a job's input or output to a specific file or a file descriptor .
Here is a list of file descriptor :
0for stdin1for stdout2for stderr- Other file descriptor is considered as invalid.
The following grammars are allowed :
command > filenameorcommand >& file descriptorcommand 0> filenameorcommand 0>& file descriptorNote: There must be no space between0and>.>(write) can also be replaced by>>(append) or<(read).command < ...will redirect stdin.command > ...will redirect stdout. If it is redirected to a file, shell will create a new file or clear original file.command >> ...will redirect stdout and append output to file.<<operator is not supported though in POSIX standard.
Shell can setup pipeline between different process. A process can read input from the output that the previous process generates.
The grammar is command1 args1 | command2 args2 | ... | commandn argsn
- Implement job control
- Support redirection grammar
- Support escape sequence
- Fixing redirection bugs
- Support environment variable assignment
- Support pipeline between commands
- Support filename expansion
