You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: labs/Shell.md
+25-22Lines changed: 25 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -125,7 +125,7 @@ The result of ```'some string'.split(/\s+/)``` is an array ```['some', 'string'
125
125
126
126
This example could have been done with ```'some string'.split(' ')``` but would not account for other types of white space or multiple white spaces.
127
127
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)
129
129
130
130
```js
131
131
stdin.on('data', function (input) {
@@ -144,7 +144,7 @@ var commands = {
144
144
'pwd':function () {
145
145
console.log(process.cwd());
146
146
},
147
-
'ls':function (args) {
147
+
'ls':function (args) {// New property added here. Note the comma on the previous line
148
148
fs.readdir(args[0] ||process.cwd(), function (err, entries) {
149
149
entries.forEach(function (e) {
150
150
console.log(e);
@@ -156,13 +156,13 @@ var commands = {
156
156
157
157
Notice this part of the ls implementation: ```args[0] || process.cwd()```
158
158
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.
160
160
161
161
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```.
162
162
163
163
## Implementing tail
164
164
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.
166
166
167
167
Implementing this will give you exposure to file streams, getting formation about a file, and useful Array functions.
168
168
@@ -188,7 +188,9 @@ First, pull in the ```fs``` module at the top of the file just after ```var stdi
188
188
var fs = require('fs');
189
189
```
190
190
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.
192
194
193
195
```
194
196
// this is declared as a property of the commands object
@@ -209,17 +211,17 @@ The stat object looks like this:
209
211
uid:501,
210
212
gid:20,
211
213
rdev:0,
212
-
size:8066,
214
+
size:8066,
213
215
blksize:4096,
214
216
blocks:16,
215
217
atime: Sat Oct 13201215:23:59GMT-0500 (CDT),
216
218
mtime: Sat Oct 13201213:40:02GMT-0500 (CDT),
217
219
ctime: Sat Oct 13201213:40:04GMT-0500 (CDT) }
218
220
```
219
221
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.
221
223
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:
223
225
224
226
```js
225
227
'tail':function (args) {
@@ -237,31 +239,32 @@ With these properties we can create a read stream that starts at the beginning o
237
239
var fileStream =fs.createReadStream(args[0], options);
238
240
239
241
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)
242
244
//bytes of the file.
243
245
});
244
246
}
245
247
```
246
248
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.
248
250
249
251
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.
250
252
253
+

254
+
251
255
```js
252
256
var numLines = (args[1] ||10) +1;
253
-
varnewLines=newArray(numLines);
254
-
var offset =0;
255
-
var index =0;
257
+
varnewLineOffsets=newArray(numLines);
258
+
var offset =0;// The offset in the file
259
+
var index =0;// The array index for storing the next newline location
256
260
257
261
fileStream.on('data', function (data) {
258
262
for (var i =0; i <data.length; i++) {
259
263
if (data[i] ==='\n') {
260
-
newLines[index] =(offset*stats.blksize)+ i;
264
+
newLineOffsets[index] = offset + i;
261
265
index =++index % numLines;
262
266
}
263
-
264
-
offset++;
267
+
offset +=data.length;
265
268
}
266
269
});
267
270
```
@@ -270,8 +273,8 @@ Now, we need to add an event listener for the ```end``` event. In this callback
270
273
271
274
```js
272
275
fileStream.on('end', function () {
273
-
if (typeofnewLines[index] ==='number') {
274
-
var position =newLines[index] +1;
276
+
if (typeofnewLineOffsets[index] ==='number') {
277
+
var position =newLineOffsets[index] +1;
275
278
}
276
279
else {
277
280
var position =0;
@@ -287,11 +290,11 @@ fileStream.on('end', function () {
287
290
});
288
291
```
289
292
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:
0 commit comments