来源:名城汉中    时间:2021-04-07 11:29

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


• 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.)


• 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. 

请加QQ:99515681 或邮箱   WX:codehelp