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/bin
where.
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 1
means move the first job to background. Note that indexing job with%n
will cause syntax error.cd
: Change work directory.cd ~/.vim
will enter~/.vim
.echo
: Print a string or something.echo $PWD
will 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 + C
which isSIGINT
, will terminate process unless handled.ctrl + D
which is actually not a signal, will write anEOF
tostdin
.ctrl + Z
which isSIGTSTP
, will suspend a process unless handled.ctrl + Y
similar 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 arg3
will executecmd1
and after it finishedcmd2
will be executed.cmd1 arg1& cmd2 arg2 &
will executecmd1
andcmd2
concurrently.fg 1
will bring the first job to foreground if existed.jobs
will 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
$VAR
will 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\06
and 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 :
0
for stdin1
for stdout2
for stderr- Other file descriptor is considered as invalid.
The following grammars are allowed :
command > filename
orcommand >& file descriptor
command 0> filename
orcommand 0>& file descriptor
Note: There must be no space between0
and>
.>
(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