设计CS350 My Shell

Lab 3: My Shell
CS350: Systems Programming
Computer Science, Emory University
Spring 2021
mysh program
a command line interpreter with input/output redirection
& Run command(s) in the background
< Redirect standard input stream from a file

Redirect standard output to a file

Redirect standard output to a file; append if file exists
| Pipe standard output of a command to standard of another
Running in the Background
• By default, shell runs command(s) in foreground
• does not prompt and fetch next command line until current command exits
• “waits” for child process(es)
• & at end of command line means run command(s) in background
• immediately print prompt and fetch next command line
• does not “wait” for child process(es)
$ cmd arg1 arg2
$ cmd2 arg1 &
no &: run in foreground
&: run in background
File I/O Redirection
• By default STDIN/STDOUT comes from/goes to the terminal
• < redirect STDIN of current command from succeeding file
• > redirect STDOUT of current command to succeeding file
• Create if file does not exist. Error if file exists.
• >> redirect STDOUT of current command to succeeding file
• Create if file does not exist. Append to file if exists.
$ cmd < f1
$ cmd2 < f1 >> f2 &
$ cmd3 >
redirect cmd1’s stdin from f1
redirect cmd2’s stdin from f1 and stdout to f2 (with append); run in background
error: no file specified for output redirection
Pipe I/O Redirection
• By default STDIN/STDOUT comes from/goes to the terminal
• I redirect STDOUT of preceding command to pipe AND redirect STDIN of
succeeding command from pipe
$ cmd1 | cmd2 > f1
$ cmd1 < f1 | cmd2 | cmd3 &
$ cmd1 > f1 | cmd
$ cmd1 | > f2
redirect cmd1’s stdout to pipe;
redirect cmd2’s stdin from pipe;
redirect cmd2’s stdout to file f2
redirect cmd1’s stdout to 1st pipe;
redirect cmd2’s stdin from 1st pipe and stdout to 2nd pipe;
redirect cmd3’s stdin from 2nd pipe;
run cmd1, cmd2 and cmd3 in background
error: redirecting cmd1’s stdout twice (ambiguous redirection)
error: no command succeeding pipe (ambiguous redirection)
Basic Shell Processing
while(1) {
commands = getCmd();
foreach command in commands:
create succeeding pipe for I/O*
create child process
open files for I/O*
redirect stdin from file or preceding pipe*
redirect stdout to file or succeeding*
execute command in child
track child pid in parent
parent waits for foreground children*
} *as necessary
Requirements
• Command lines are restricted to 1024 characters or less.
• You may use wait() and wait3(), but not waitpid(), wait4() nor any other variant.
• When executed in the foreground, mysh waits for all processes in a pipe to complete.
• Transient zombies may exist, but mysh should periodically clean them up
• Close unneeded file descriptors: When child calls exec(), only 0, 1, 2 should be open
• Handle all error cases, including operator misuse and missing commands on the command line.
• If a command line is malformed (i.e. syntactically incorrect), no part of it should be executed.
(You do not need to check whether commands are valid or executable.)
Tips
• You may use the provided tokens.[c,h] files to “tokenize” your command lines.
• Use fgets() to read input lines.
• Check fgets() and wait() for premature returns due to system interruption
• if fgets() or wait() fails and errno == EINTR, try the call again!
• Always check execvp() return value for failure
• In execvp()’s argument vector, first element is the command and last element is NULL.
• Track foreground process pids to ensure all terminate before fetching next command line.
• Kill all stray processes left around after quitting mysh
• Parse command line into composite commands. FWIW:
• I created a CmdSet struct and a Cmd struct: CmdSet contains an array of Cmds, one for each command,
and foreground/background flag
• Cmd Struct contains the command’s argument vector, input filename (if redirected) and output filename
(if redirected)
• Consider parsing the command line completely before executing any part of it.
• Consider a background process terminating while a foreground process running: make sure
mysh doesn’t fetch a new command line before a foreground process terminates.

你可能感兴趣的:(后端)