Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due
CS 131: Operating Systems Programming Assignment 1, Part 1
Getting Started
Common shell
|
Information |
What you need to know |
Link |
|
What is Unix? |
Theoretical |
http://www.ee.surrey.ac.uk/Teaching/Unix/unixintro.html |
|
Working Directory Commands |
ls, cd, . , .. , pwd |
http://www.ee.surrey.ac.uk/Teaching/Unix/unix1.html |
|
Basic Text Operations |
cat, grep, wc, uniq |
http://www.ee.surrey.ac.uk/Teaching/Unix/unix2.html |
|
Redirection and Piping |
Redirection, Piping,> | |
http://www.ee.surrey.ac.uk/Teaching/Unix/unix3.html |
REPL Loop
Thank you for using the Unix-ish command line. Goodbye!
Your REPL must read user commands from System.in. There are two critical functions within this loop. (1) Correctly parsing commands in a way that allows the creation of piped filters. Using Scanner and String.split will help you with this task. (2) Each function identifies and reports different errors as follows.
Invalid Property
Expected Behavior
Undefined Command
Invalid Arguments
Invalid Piping Order
File/Directory Not Found
Your REPL loop must support simple directory commands: ls, cd, and pwd. cd is the only command you will implement that does not use String queues, because it does not take piped input and does not produce output. You may handle this case without inheriting from the SequentialFilterclass (see REPL classes defined below). ls and pwd do create piped output, even though they don't need piped input (the same is true for cat).
The directory from which you start the command line program should be initialized as the current working directory that your Java program is initialized to. The working directory can be modified with the cd command. You use the command ls to list the contents of the current working directory. This will be a little more challenging than you might think because you are not allowed to modify the invoking environment's working directory. You'll need to manage a separate working directory for your shell. This can be as simple as maintaining a String that keeps track of your present working directory.
Filter Commands
All commands that you have to implement within this half of the programming assignment must implement the abstract SequentialFilter.java class. The sequential filter is a convenient abstraction: it reads from an input queue (linked list), and writes to an output queue, by calling a method called process(). The queue that it writes to is the input queue for the next filter (if there is a next filter). Shown below is the abstract class SequentialFilter, which should greatly help you along in this project. SequentialFilter inherits from Filter, a class that is not displayed here, but is given along with this assignment.
On the next page of the assignment, there is a table detailing the commands you are responsible for implementing. A proper implementation of each should refer back to the correct error messages to print, and the behavior expected of each in a Unix-like system.
public abstract class SequentialFilter extends Filter {
protected Queue<String> input;protected Queue<String> output;public void setPrevFilter(Filter prevFilter) {
prevFilter.setNextFilter(this);
}
public void setNextFilter(Filter nextFilter) {
if (nextFilter instanceof SequentialFilter){
SequentialFilter sequentialNext =(SequentialFilter) nextFilter;this.next = sequentialNext;sequentialNext.prev = this;if (this.output == null){
this.output = new LinkedList<String>();
}
sequentialNext.input = this.output;
} else {
throw new RuntimeException("Should notattempt to link dissimilar filter types.");
}
}
public void process(){
while (!input.isEmpty()){
String line = input.poll();String processedLine = processLine(line);if (processedLine != null){
output.add(processedLine);
}
}
}
public boolean isDone() { return input.size() == 0; }protected abstract String processLine(String line);
|
Command |
Piped input |
Piped output |
Short Description |
Notes |
|
File System Navigation Commands |
||||
|
pwd |
No |
Yes |
Pipes the working directory to the output message queue |
You may want to use the Java File class (also see the slide about the File class in the slides from the first tutorial). You can also use System calls to achieve this. |
|
ls |
No |
Yes |
Pipes the contents of the current working directory to the output message queue |
You do not need to allow arguments to ls, that is, ls can just always output the contents of the current working directory. You do not need to include "." or ".." in the list. You also do not need to mark directories with any special characters. |
|
cd |
No |
No |
Change to another directory relative to the current directory |
Make sure you can accept the special directories "." (the current directory) and ".." (one directory up in the directory hierarchy). You do not need to support absolute paths. You do notneed to support up-down paths (i.e. cd ../hello/world). Important note: the cd command is the only command (other than exit) that does not need to participate in the piping mechanism, it can only output errors, it never accepts piped input or sends piped output. For this reason, your implementation of the cd command can be simpler than your implementation of the other commands. |
|
Text Manipulation Commands |
||||
|
cat |
No |
Yes |
Output the entirety of one or more files to the output message queue |
Unlike in UNIX, cat does not accept piped input. I.e. for your program, cat will always be first in a string of commands separated by pipes. The cat command in a proper UNIX shell has significantly more functionality than the version we require you to implement, you need only implement the output capability. |
|
grep
|
Yes |
Yes |
Read lines from piped input, and only output lines with a given search string |
You do not need to do regular expression matching. You should do a simple case -sensitive string search, and count any line containing that search string as a match. You can assume that this argument (as well as all file names) will never contain >, or |. |
|
wc |
Yes |
Yes |
Read lines from piped input and output the number of lines, words and characters, separated with space |
Note that this command heavily relies on figuring out when it is going to stop getting more input lines to count. Consider the possibility that there are no lines returned. Make sure that you utilize the isDone()method of this filter and the previous filter. |
|
uniq |
Yes |
Yes |
Filters out duplicate lines from the input |
Only permits lines of input to pass through if they have not been detected before (the Collections framework can be useful here). |
|
> |
Yes |
No |
Reads piped input, and writes it to a file specified after the > symbol |
Make sure to utilize the java File class for this operation. If a file exists with the name given by the command, it should be overwritten by a new file created in its place. |
|
General Commands: |
||||
|
exit |
No |
No |
Quit the command line |
Like cd, the exit command can be very simple, and it should just end your REPL and return from your main method after printing the "goodbye" message. |
Wrap It Up: What Do You Have And What You Need To Do
AllSequentialTests.java, RedirectionTests.java, REPLTests.java, TextProcessingTests.java, WorkingDirectoryTests.java:
These files contain multiple tests that examine your implementation of the various commands. You should not modify these classes (besides for debugging purposes). Note that a failure of any of these tests will certainly lead to deducted points. All perfect assignments will pass all tests, but passing the tests does not guarantee a perfect score (Implication).
Testing and Grading
Successful completion of this project is nearly impossible without appropriately testing against the provided JUnit Tests. If you cannot run the tests when you import your project, please see a TA at office hours as soon as possible.
Importing and exporting properly is crucial to allow us to grade your projects properly. Please import and export based on the instructions in the tutorial slides and on LATTE, and submit the zip file that you exported from Eclipse. If you fail to export your project properly, you may be penalized.
You will need to include Javadocs together with the code you submit. You should consult our guide on how to write and generate Javadocs on Latte and make sure you include the entire ‘doc’ folder in your submission. Failure to include Javadocs will be penalized.
To allow us to test without changing your code, please name the class which houses your main method SequentialREPL.java, this will be called when the test suite is run. Because we will be using unit tests that will compare your output (System.out) character for character against our samples, please make sure that your error messages are exactly the same as the ones given, and that there are no intentional or unintentional discrepancies (whitespaces, prompt, wording) between your result and the examples provided. Tests will fail if these discrepancies exist, and a good first place to check a test failure is the exact strings being compared.
There is a helpful Boolean variable called “DEBUGGING_MODE” (In the Test Suite), which when set to true will not clean up after the created files and directories after unit tests are run. This can allow you to see the error in your output (files stored in the current working directory), and potentially understand any disconnect between our expectations and your code. Feel free to play around with the tests (modify them as is helpful for your debugging, etc.), but know that you will be graded against the set of tests that we sent out originally. Any attempt to tamper with the tests will be considered a breach of academic integrity, and will result in point penalties and potentially further discipline.
Note on differences between Unit Tests and Integration Tests
Please note that though JUnit is being used to run this suite of tests, these are not unit tests, but integration tests. Do not take this test design as an appropriate way to test the code that you are writing. Unit tests test specific functions and small, incremental pieces of code. These tests are predicated on the entirety of your code being complete, and this assumption breaks most of the conventions of unit test writing.