Skip to content

Commit caf5096

Browse files
committed
Added image and updated shell lab
1 parent ecdd443 commit caf5096

2 files changed

Lines changed: 25 additions & 22 deletions

File tree

labs/Shell.md

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ The result of ```'some string'.split(/\s+/)``` is an array ```['some', 'string'
125125

126126
This example could have been done with ```'some string'.split(' ')``` but would not account for other types of white space or multiple white spaces.
127127

128-
For example: ```'some__string'.split('_')``` would result in ```['some', '', 'string']```
128+
For example: ```'some__string'.split('_')``` would result in ```['some', '', 'string']``` (underscores used because multiple consecutive white spaces were ignored by Markdown parser)
129129

130130
```js
131131
stdin.on('data', function (input) {
@@ -144,7 +144,7 @@ var commands = {
144144
'pwd': function () {
145145
console.log(process.cwd());
146146
},
147-
'ls': function (args) {
147+
'ls': function (args) { // New property added here. Note the comma on the previous line
148148
fs.readdir(args[0] || process.cwd(), function (err, entries) {
149149
entries.forEach(function (e) {
150150
console.log(e);
@@ -156,13 +156,13 @@ var commands = {
156156

157157
Notice this part of the ls implementation: ```args[0] || process.cwd()```
158158

159-
Unlike many other languages, JavaScript doesn't care if you access an index out of bounds of an array. If an element does not exist ```undefined``` will be returned. Using the ```x || y``` syntax will test the existence of x and if it doesn't exist will return y. This is a common pattern for assigning a default value.
159+
Unlike many other languages, JavaScript doesn't care if you access an index out of bounds of an array. If an element does not exist at the index ```undefined``` will be returned. Using the ```x || y``` syntax will test the existence of ```x``` and if it doesn't exist will evaluate to ```y```. This is a common pattern for assigning a default value.
160160

161161
Feel free to implement your favorite shell command as an exercise or follow along with the next part of this lab where we'll implement ```tail```.
162162

163163
## Implementing tail
164164

165-
```tail [N]```: prints the last N lines of a file. This requires us to locate all of the newlines in a file and trim down to last N number of lines to print. If N is not specified we'll print the last 10 lines.
165+
```tail filename [N]```: prints the last N lines of a file. This requires us to locate all of the newlines in a file and trim down to last N number of lines to print. If N is not specified we'll print the last 10 lines.
166166

167167
Implementing this will give you exposure to file streams, getting formation about a file, and useful Array functions.
168168

@@ -188,7 +188,9 @@ First, pull in the ```fs``` module at the top of the file just after ```var stdi
188188
var fs = require('fs');
189189
```
190190

191-
Get the length of the file in bytes. To do this we'll need to stat the file path provided as the first argument.
191+
Get the length of the file in bytes.
192+
193+
To do this we'll need to stat the file path provided as the first argument.
192194

193195
```
194196
// this is declared as a property of the commands object
@@ -209,17 +211,17 @@ The stat object looks like this:
209211
uid: 501,
210212
gid: 20,
211213
rdev: 0,
212-
size: 8066,
214+
size: 8066,
213215
blksize: 4096,
214216
blocks: 16,
215217
atime: Sat Oct 13 2012 15:23:59 GMT-0500 (CDT),
216218
mtime: Sat Oct 13 2012 13:40:02 GMT-0500 (CDT),
217219
ctime: Sat Oct 13 2012 13:40:04 GMT-0500 (CDT) }
218220
```
219221

220-
We're concerned with the size and blksize properties for this exercise.
222+
We're concerned with the size and blksize properties of the stat object for this exercise.
221223

222-
With these properties we can create a read stream that starts at the beginning of the file and continues until to the end. Each ```blksize``` bytes of the file will be provided to us through a callback. Here's the implementation:
224+
With these properties we can create a read stream that starts at the beginning of the file and continues to the end. Each ```blksize``` bytes of the file will be provided to us through a callback. Here's the implementation:
223225

224226
```js
225227
'tail': function (args) {
@@ -237,31 +239,32 @@ With these properties we can create a read stream that starts at the beginning o
237239
var fileStream = fs.createReadStream(args[0], options);
238240

239241
fileStream.on('data', function (data) {
240-
//This anonymous function (callback) will be
241-
//executed for every blksize(bufferSize from options)
242+
//This callback (anonymous function) will be
243+
//executed for every blksize (bufferSize from options)
242244
//bytes of the file.
243245
});
244246
}
245247
```
246248

247-
In our callback we'll examine each character to see if it's a newline ```\n```.
249+
In our callback we'll examine each character in the buffer to see if it's a newline ```\n```. For each new line we'll track the byte offset for which it occurred in the file.
248250

249251
We'll create an array to store the byte offset of each newline for the last N+1 lines. The +1 is so we can keep around an extra trailing line to start reading from.
250252

253+
![Algorithm Explained](/path/to/img.jpg "An illustration of the algorithm in use.")
254+
251255
```js
252256
var numLines = (args[1] || 10) + 1;
253-
var newLines = new Array(numLines);
254-
var offset = 0;
255-
var index = 0;
257+
var newLineOffsets = new Array(numLines);
258+
var offset = 0; // The offset in the file
259+
var index = 0; // The array index for storing the next newline location
256260

257261
fileStream.on('data', function (data) {
258262
for (var i = 0; i < data.length; i++) {
259263
if (data[i] === '\n') {
260-
newLines[index] = (offset * stats.blksize) + i;
264+
newLineOffsets[index] = offset + i;
261265
index = ++index % numLines;
262266
}
263-
264-
offset++;
267+
offset += data.length;
265268
}
266269
});
267270
```
@@ -270,8 +273,8 @@ Now, we need to add an event listener for the ```end``` event. In this callback
270273

271274
```js
272275
fileStream.on('end', function () {
273-
if (typeof newLines[index] === 'number') {
274-
var position = newLines[index] + 1;
276+
if (typeof newLineOffsets[index] === 'number') {
277+
var position = newLineOffsets[index] + 1;
275278
}
276279
else {
277280
var position = 0;
@@ -287,11 +290,11 @@ fileStream.on('end', function () {
287290
});
288291
```
289292

290-
If you're new to JavaScript you may be confused by the check to see if an element is a number. This ensures ```newLines[index]``` has been set to a number. If the value was never set it would be ```undefined```. Alternatively, this could have been:
293+
If you're new to JavaScript you may be confused by the check to see if an element is a number. This ensures ```newLineOffsets[index]``` has been set to a number. If the value was never set it would be ```undefined```. Alternatively, this could have been:
291294

292295
```js
293-
if (typeof newLines[index] !== 'undefined') {
294-
var position = newLines[index] + 1;
296+
if (typeof newLineOffsets[index] !== 'undefined') {
297+
var position = newLineOffsets[index] + 1;
295298
} else {
296299
var position = 0;
297300
}

labs/last4lines.png

60.3 KB
Loading

0 commit comments

Comments
 (0)