Skip to content

Commit 8668211

Browse files
committed
01 Implement shell tools (cat, ls, wc) in JS with mode
1 parent 407b010 commit 8668211

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

implement-shell-tools/cat/cat.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import process from "node:process";
2+
import { promises as fs } from "node:fs";
3+
4+
const arrArgv = process.argv.slice(2);
5+
6+
const numberLines = arrArgv.includes("-n");
7+
const numberNonemptyLines = arrArgv.includes("-b");
8+
9+
const nonFlagArrArgv = arrArgv.filter((arr) => !arr.startsWith("-"));
10+
11+
let number = 1;
12+
13+
for (let file of nonFlagArrArgv) {
14+
const content = await fs.readFile(file, "utf-8");
15+
16+
const linedText = content.split("\n");
17+
18+
const numbered = linedText.map((line) => {
19+
if (numberNonemptyLines) {
20+
if (line.trim() === "") {
21+
return line;
22+
} else {
23+
return `${String(number++).padStart(3)} ${line}`;
24+
}
25+
}
26+
if (numberLines) {
27+
return `${String(number++).padStart(3)} ${line}`;
28+
}
29+
30+
return line;
31+
});
32+
console.log(numbered.join("\n"));
33+
}

implement-shell-tools/ls/ls.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import process from "node:process";
2+
import { promises as fs } from "node:fs";
3+
import path from "node:path";
4+
5+
const arrArgv = process.argv.slice(2);
6+
7+
const longFormat = arrArgv.includes("-l");
8+
const showHidden = arrArgv.includes("-a");
9+
10+
const paths = arrArgv.filter((argv) => !argv.startsWith("-"));
11+
if (paths.length === 0) path = "[.]";
12+
13+
for (let listFile of paths) {
14+
const status = await fs.stat(listFile);
15+
16+
if (status.isFile()) {
17+
const permissions = (status.mode & 0o777).toString(8);
18+
const sizeFile = status.size;
19+
const owner = status.uid;
20+
const group = status.gid;
21+
const timeMod = status.mtime.toLocaleString();
22+
23+
if (longFormat) {
24+
console.log(
25+
`${permissions}, ${owner}, ${group}, ${sizeFile}, ${timeMod}, ${listFile}`
26+
);
27+
} else {
28+
console.log(listFile);
29+
}
30+
} else {
31+
let files = await fs.readdir(listFile, { withFileTypes: true });
32+
33+
if (!showHidden) {
34+
files = files.filter((file) => !file.name.startsWith("."));
35+
}
36+
37+
for (let file of files) {
38+
const wholePath = path.join(listFile, file.name);
39+
const statusFile = await fs.stat(wholePath);
40+
41+
const permissions = (statusFile.mode & 0o777).toString(8);
42+
const sizeFile = statusFile.size;
43+
const owner = statusFile.uid;
44+
const group = statusFile.gid;
45+
const timeMod = statusFile.mtime.toLocaleString();
46+
47+
if (longFormat) {
48+
console.log(
49+
`${permissions}, ${owner}, ${group}, ${sizeFile}, ${timeMod}, ${file.name}`
50+
);
51+
} else {
52+
console.log(file.name);
53+
}
54+
}
55+
}
56+
}

implement-shell-tools/wc/wc.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import process from "node:process";
2+
import { promises as fs } from "node:fs";
3+
4+
const arrArgv = process.argv.slice(2);
5+
6+
const lines = arrArgv.includes("-l");
7+
const words = arrArgv.includes("-w");
8+
const bytes = arrArgv.includes("-c");
9+
10+
const noFlags = !lines && !words && !bytes;
11+
12+
const paths = arrArgv.filter((argv) => !argv.startsWith("-"));
13+
14+
for (let path of paths) {
15+
const context = await fs.readFile(path, "utf-8");
16+
17+
const countLines = context.split(/\r?\n/).length;
18+
const countWords = context.split(/\s+/).length;
19+
const countBytes = Buffer.byteLength(context, "utf-8");
20+
21+
let startInput = "";
22+
23+
if (noFlags || lines) {
24+
startInput += `${countLines} `;
25+
}
26+
27+
if (noFlags || words) {
28+
startInput += `${countWords} `;
29+
}
30+
31+
if (noFlags || bytes) {
32+
startInput += `${countBytes} `;
33+
}
34+
35+
startInput += path;
36+
37+
console.log(startInput);
38+
}

0 commit comments

Comments
 (0)