buninu-linux 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -22
- package/fetch-alpine.sh +9 -4
- package/initramfs/bin/ip +2 -1
- package/initramfs/bin/mount +2 -1
- package/initramfs/bin/poweroff +6 -27
- package/initramfs/bin/ps +256 -0
- package/initramfs/bin/reboot +10 -0
- package/initramfs/bin/tar +169 -0
- package/initramfs/bin/top +129 -0
- package/initramfs/bin/umount +2 -1
- package/initramfs/buninu/apps/bunmsh/CHANGELOG.md +36 -0
- package/initramfs/buninu/apps/bunmsh/README.md +7 -0
- package/initramfs/buninu/apps/bunmsh/package.json +1 -1
- package/initramfs/buninu/apps/bunmsh/src/fancy-ls.js +29 -14
- package/initramfs/buninu/apps/bunmsh/src/line-edit.js +43 -0
- package/initramfs/buninu/apps/bunmsh/src/main.js +15 -1
- package/initramfs/buninu/apps/bunmsh/src/mouse.js +29 -4
- package/initramfs/buninu/apps/bunmsh/src/shell.js +9 -1
- package/initramfs/buninu/apps/bunmsh/test/shell1.test.js +70 -0
- package/initramfs/buninu/apps/jsmdcui/CHANGELOG.md +10 -0
- package/initramfs/buninu/apps/jsmdcui/README.md +2 -0
- package/initramfs/buninu/apps/jsmdcui/package.json +1 -1
- package/initramfs/buninu/apps/jsmdcui/runtime/help/commands.md +4 -1
- package/initramfs/buninu/apps/jsmdcui/runtime/help/help.md +2 -0
- package/initramfs/buninu/apps/jsmdcui/src/index.js +40 -13
- package/initramfs/buninu/package.json +1 -1
- package/initramfs/lib/dlopen.js +0 -9
- package/initramfs/lib/document.js +6 -0
- package/initramfs/lib/power.js +35 -0
- package/initramfs/usr/share/doc/buninu-linux/ps.md +94 -0
- package/initramfs/usr/share/doc/buninu-linux/reboot.md +15 -0
- package/initramfs/usr/share/doc/buninu-linux/tar.md +73 -0
- package/initramfs/usr/share/doc/buninu-linux/top.md +23 -0
- package/package.json +2 -2
|
@@ -53,6 +53,7 @@ import { fancyLs } from "../src/fancy-ls.js";
|
|
|
53
53
|
import { MOUSE_OFF, MOUSE_ON, mouseInput } from "../src/mouse.js";
|
|
54
54
|
import { canonicalEnvironment, environmentValue, homeRelativePath } from "../src/environment.js";
|
|
55
55
|
import { findIsRegularBuiltin } from "../src/find.js";
|
|
56
|
+
import { toggleSavedText } from "../src/line-edit.js";
|
|
56
57
|
|
|
57
58
|
async function run(source, options = {}) {
|
|
58
59
|
const state = createState({
|
|
@@ -181,6 +182,36 @@ describe("completion", () => {
|
|
|
181
182
|
]);
|
|
182
183
|
});
|
|
183
184
|
|
|
185
|
+
test("toggles independently saved Ctrl-U heads and Ctrl-K tails", () => {
|
|
186
|
+
const cutHead = toggleSavedText("headtail", 4, "", "head");
|
|
187
|
+
expect(cutHead).toEqual({ line: "tail", cursor: 0, saved: "head", changed: true });
|
|
188
|
+
expect(toggleSavedText(cutHead.line, cutHead.cursor, cutHead.saved, "head"))
|
|
189
|
+
.toEqual({ line: "headtail", cursor: 4, saved: "", changed: true });
|
|
190
|
+
|
|
191
|
+
const cutTail = toggleSavedText("headtail", 4, "", "tail");
|
|
192
|
+
expect(cutTail).toEqual({ line: "head", cursor: 4, saved: "tail", changed: true });
|
|
193
|
+
expect(toggleSavedText(cutTail.line, cutTail.cursor, cutTail.saved, "tail"))
|
|
194
|
+
.toEqual({ line: "headtail", cursor: 4, saved: "", changed: true });
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test("intercepts Ctrl-U and Ctrl-K outside bracketed paste", async () => {
|
|
198
|
+
const edits = [];
|
|
199
|
+
const pasted = [];
|
|
200
|
+
let forwarded = "";
|
|
201
|
+
const input = mouseInput(() => {}, () => {}, () => {},
|
|
202
|
+
(text) => pasted.push(text),
|
|
203
|
+
(side) => edits.push({ side, forwarded }));
|
|
204
|
+
input.on("data", (chunk) => { forwarded += chunk.toString(); });
|
|
205
|
+
input.end("abc\x15def\x0b\x1b[200~x\x15y\x0bz\x1b[201~");
|
|
206
|
+
await new Promise((resolve) => input.once("end", resolve));
|
|
207
|
+
expect(edits).toEqual([
|
|
208
|
+
{ side: "head", forwarded: "abc" },
|
|
209
|
+
{ side: "tail", forwarded: "abcdef" },
|
|
210
|
+
]);
|
|
211
|
+
expect(forwarded).toBe("abcdef");
|
|
212
|
+
expect(pasted).toEqual(["x\x15y\x0bz"]);
|
|
213
|
+
});
|
|
214
|
+
|
|
184
215
|
test("imports Bash and Fish history by default and can be disabled", async () => {
|
|
185
216
|
expect(parseBashHistory("#1720000000\necho bash\n\nshared\n"))
|
|
186
217
|
.toEqual(["echo bash", "shared"]);
|
|
@@ -575,6 +606,7 @@ describe("execution", () => {
|
|
|
575
606
|
mkdirSync(join(cwd, "targetdir"));
|
|
576
607
|
symlinkSync("target.txt", join(cwd, "link_ok"));
|
|
577
608
|
symlinkSync("targetdir", join(cwd, "link_dir"));
|
|
609
|
+
await Bun.write(join(cwd, "targetdir", "inside.js"), "export {};\n");
|
|
578
610
|
symlinkSync("/nonexistent/path", join(cwd, "link_broken"));
|
|
579
611
|
symlinkSync("loop_b", join(cwd, "loop_a"));
|
|
580
612
|
symlinkSync("loop_a", join(cwd, "loop_b"));
|
|
@@ -597,6 +629,15 @@ describe("execution", () => {
|
|
|
597
629
|
const plain = await run("builtin lsfancy", { cwd });
|
|
598
630
|
expect(plain.stdout).toContain("🔗 link_ok");
|
|
599
631
|
expect(plain.stdout).toContain("🚫 link_broken");
|
|
632
|
+
|
|
633
|
+
// A command-line link to a directory is followed for an ordinary
|
|
634
|
+
// listing, but -l, -d, and -F inspect/classify the link itself.
|
|
635
|
+
const followed = await run("builtin lsfancy link_dir", { cwd });
|
|
636
|
+
expect(followed.stdout).toContain("inside.js");
|
|
637
|
+
const linkLong = await run("builtin lsfancy -l link_dir", { cwd });
|
|
638
|
+
expect(linkLong.stdout).toContain("link_dir -> targetdir");
|
|
639
|
+
expect((await run("builtin lsfancy -d link_dir", { cwd })).stdout).toContain("🔗 link_dir");
|
|
640
|
+
expect((await run("builtin lsfancy -F link_dir", { cwd })).stdout).toContain("link_dir@");
|
|
600
641
|
} finally { rmSync(cwd, { recursive: true, force: true }); }
|
|
601
642
|
});
|
|
602
643
|
|
|
@@ -624,6 +665,35 @@ describe("execution", () => {
|
|
|
624
665
|
} finally { rmSync(cwd, { recursive: true, force: true }); }
|
|
625
666
|
});
|
|
626
667
|
|
|
668
|
+
test("builtin ls lists glob-expanded files as files, not directory sections", async () => {
|
|
669
|
+
const cwd = mkdtempSync(join(tmpdir(), "bunmsh-ls-glob-"));
|
|
670
|
+
try {
|
|
671
|
+
await Bun.write(join(cwd, "first.sh"), "#!/bin/sh\n");
|
|
672
|
+
await Bun.write(join(cwd, "final.sh"), "#!/bin/sh\n");
|
|
673
|
+
await Bun.write(join(cwd, "other.txt"), "other\n");
|
|
674
|
+
const output = await run("builtin ls f*.sh", { cwd });
|
|
675
|
+
expect(output).toMatchObject({ status: 0, stderr: "" });
|
|
676
|
+
expect(output.stdout).toContain("first.sh");
|
|
677
|
+
expect(output.stdout).toContain("final.sh");
|
|
678
|
+
expect(output.stdout).not.toContain("other.txt");
|
|
679
|
+
expect(output.stdout).not.toContain("first.sh:");
|
|
680
|
+
expect(output.stdout).not.toContain("final.sh:");
|
|
681
|
+
expect(output.stdout).not.toContain("\n\n");
|
|
682
|
+
|
|
683
|
+
await Bun.write(join(cwd, "-odd"), "odd\n");
|
|
684
|
+
const afterDoubleDash = await run("builtin ls -- -odd", { cwd });
|
|
685
|
+
expect(afterDoubleDash).toMatchObject({ status: 0, stderr: "" });
|
|
686
|
+
expect(afterDoubleDash.stdout).toContain("-odd");
|
|
687
|
+
|
|
688
|
+
mkdirSync(join(cwd, ".hidden-target"));
|
|
689
|
+
await Bun.write(join(cwd, ".hidden-target", "through-link.js"), "export {};\n");
|
|
690
|
+
symlinkSync(".hidden-target", join(cwd, "class-link"));
|
|
691
|
+
const throughLink = await run("builtin ls ./*/*.js", { cwd });
|
|
692
|
+
expect(throughLink).toMatchObject({ status: 0, stderr: "" });
|
|
693
|
+
expect(throughLink.stdout).toContain("./class-link/through-link.js");
|
|
694
|
+
} finally { rmSync(cwd, { recursive: true, force: true }); }
|
|
695
|
+
});
|
|
696
|
+
|
|
627
697
|
test("fallback find filters paths and supports both -exec modes", async () => {
|
|
628
698
|
const cwd = mkdtempSync(join(tmpdir(), "bunmsh-find-"));
|
|
629
699
|
try {
|
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable user-visible changes to jsmdcui are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.19.2] - 2026-09-21
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Quickly pressing `Ctrl-W` twice now switches to the next tab like `Alt-T`
|
|
10
|
+
from either an editor or terminal pane. A single press retains its existing
|
|
11
|
+
next-pane behavior. At the rightmost tab, when every tab contains only
|
|
12
|
+
terminal panes, the double press creates a new editor tab instead of cycling
|
|
13
|
+
back, ensuring keyboard-only access to editing and other non-terminal work.
|
|
14
|
+
|
|
5
15
|
## [0.19.0] - 2026-08-24
|
|
6
16
|
|
|
7
17
|
### Fixed
|
|
@@ -793,6 +793,8 @@ selection, search, and copy remain available.
|
|
|
793
793
|
| `Ctrl-F` | Search; use `Ctrl-N` and `Ctrl-P` for the next and previous match. |
|
|
794
794
|
| `Ctrl-G` | Open the editor help. |
|
|
795
795
|
| `Alt-G` | Show or hide the shortcut bar. |
|
|
796
|
+
| `Ctrl-W` | Switch to the next pane in the current tab. |
|
|
797
|
+
| `Ctrl-W` twice quickly | Switch to the next tab like `Alt-T`. At the rightmost tab, if every tab contains only terminal panes, create a new editor tab instead of cycling back. |
|
|
796
798
|
| `Ctrl-Q` or `Alt-Q` | Close the current UI. |
|
|
797
799
|
|
|
798
800
|
To preview another color theme, press `Ctrl-E` or click on `€`, type `theme `, then use `Tab`
|
|
@@ -151,7 +151,10 @@ quotes here but these are not necessary when entering the command in micro.
|
|
|
151
151
|
|
|
152
152
|
* `term ['exec']`: Open a terminal emulator running the given executable. If no
|
|
153
153
|
executable is given, this will open the default shell in the terminal
|
|
154
|
-
emulator.
|
|
154
|
+
emulator. `Ctrl-W` switches panes in both editor and terminal panes. Press
|
|
155
|
+
it twice quickly to cycle to the next tab like `Alt-T`; at the rightmost
|
|
156
|
+
tab, if every tab is a terminal, this creates a new editor tab instead of
|
|
157
|
+
cycling back.
|
|
155
158
|
|
|
156
159
|
---
|
|
157
160
|
|
|
@@ -793,6 +793,8 @@ selection, search, and copy remain available.
|
|
|
793
793
|
| `Ctrl-F` | Search; use `Ctrl-N` and `Ctrl-P` for the next and previous match. |
|
|
794
794
|
| `Ctrl-G` | Open the editor help. |
|
|
795
795
|
| `Alt-G` | Show or hide the shortcut bar. |
|
|
796
|
+
| `Ctrl-W` | Switch to the next pane in the current tab. |
|
|
797
|
+
| `Ctrl-W` twice quickly | Switch to the next tab like `Alt-T`. At the rightmost tab, if every tab contains only terminal panes, create a new editor tab instead of cycling back. |
|
|
796
798
|
| `Ctrl-Q` or `Alt-Q` | Close the current UI. |
|
|
797
799
|
|
|
798
800
|
To preview another color theme, press `Ctrl-E` or click on `€`, type `theme `, then use `Tab`
|
|
@@ -2796,6 +2796,8 @@ class App {
|
|
|
2796
2796
|
this.tabRects = [];
|
|
2797
2797
|
this._escBuf = null; // pending lone ESC bytes waiting for alt-key combo
|
|
2798
2798
|
this._escTimer = null;
|
|
2799
|
+
this._ctrlWTime = 0;
|
|
2800
|
+
this._ctrlWTimer = null;
|
|
2799
2801
|
this._suggestionsRow = null;
|
|
2800
2802
|
this._suggestionRects = [];
|
|
2801
2803
|
this._acHScroll = 0;
|
|
@@ -3790,7 +3792,7 @@ class App {
|
|
|
3790
3792
|
const titleStyle = { ...defaultStyle, reverse: true };
|
|
3791
3793
|
const scrollMsg = vt && vt.scrollOffset > 0
|
|
3792
3794
|
? ` -- SCROLLBACK (${vt.scrollOffset}/${vt.scrollback.length}) wheel↑↓ to browse, any key to return`
|
|
3793
|
-
: (isActive ? " [Esc
|
|
3795
|
+
: (isActive ? " [Esc=close,Ctrl-W/*2=Next Pane/Tab]" : "");
|
|
3794
3796
|
putText(this.screen, pane.x, pane.y, ` Terminal${scrollMsg}`.padEnd(pane.w), titleStyle, pane.w);
|
|
3795
3797
|
if (!vt) return;
|
|
3796
3798
|
const renderRows = pane.h - 1;
|
|
@@ -4228,14 +4230,12 @@ class App {
|
|
|
4228
4230
|
this.render();
|
|
4229
4231
|
return;
|
|
4230
4232
|
}
|
|
4231
|
-
// Ctrl-W: switch pane focus without closing
|
|
4233
|
+
// Ctrl-W: switch pane focus without closing. A quick second Ctrl-W
|
|
4234
|
+
// cycles tabs, with an editor-tab escape hatch when every tab is a
|
|
4235
|
+
// terminal and the current one is already the rightmost tab.
|
|
4232
4236
|
if (text === "\x17") {
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
const idx = panes.indexOf(this.tab.activePane);
|
|
4236
|
-
this.tab.activePane = panes[(idx + 1) % panes.length];
|
|
4237
|
-
this.render();
|
|
4238
|
-
}
|
|
4237
|
+
await this.handleCtrlW();
|
|
4238
|
+
this.render();
|
|
4239
4239
|
return;
|
|
4240
4240
|
}
|
|
4241
4241
|
|
|
@@ -4525,11 +4525,7 @@ class App {
|
|
|
4525
4525
|
await runAction("AddTab", this);
|
|
4526
4526
|
break;
|
|
4527
4527
|
case "ctrl-w": { //switchPane
|
|
4528
|
-
|
|
4529
|
-
if (panes.length > 1) {
|
|
4530
|
-
const idx = panes.indexOf(this.tab.activePane);
|
|
4531
|
-
this.tab.activePane = panes[(idx + 1) % panes.length];
|
|
4532
|
-
}
|
|
4528
|
+
await this.handleCtrlW();
|
|
4533
4529
|
break;
|
|
4534
4530
|
}
|
|
4535
4531
|
case "ctrl-y": //redo
|
|
@@ -5403,6 +5399,37 @@ class App {
|
|
|
5403
5399
|
return this.setActiveTab((this.activeTabIdx + 1) % this.tabs.length);
|
|
5404
5400
|
}
|
|
5405
5401
|
|
|
5402
|
+
_clearCtrlW() {
|
|
5403
|
+
if (this._ctrlWTimer) clearTimeout(this._ctrlWTimer);
|
|
5404
|
+
this._ctrlWTimer = null;
|
|
5405
|
+
this._ctrlWTime = 0;
|
|
5406
|
+
}
|
|
5407
|
+
|
|
5408
|
+
async handleCtrlW() {
|
|
5409
|
+
const now = Date.now();
|
|
5410
|
+
const isDouble = this._ctrlWTime > 0 && now - this._ctrlWTime < 400;
|
|
5411
|
+
this._clearCtrlW();
|
|
5412
|
+
|
|
5413
|
+
if (isDouble) {
|
|
5414
|
+
const atRightmostTab = this.activeTabIdx === this.tabs.length - 1;
|
|
5415
|
+
const allTabsAreTerminal = this.tabs.every((tab) =>
|
|
5416
|
+
tab.panes().length > 0 && tab.panes().every((pane) => pane.type === "term")
|
|
5417
|
+
);
|
|
5418
|
+
if (atRightmostTab && allTabsAreTerminal) await this.addTab();
|
|
5419
|
+
else this.nextTab();
|
|
5420
|
+
return;
|
|
5421
|
+
}
|
|
5422
|
+
|
|
5423
|
+
this._ctrlWTime = now;
|
|
5424
|
+
this._ctrlWTimer = setTimeout(() => this._clearCtrlW(), 400);
|
|
5425
|
+
|
|
5426
|
+
const panes = this.tab.panes();
|
|
5427
|
+
if (panes.length > 1) {
|
|
5428
|
+
const idx = panes.indexOf(this.tab.activePane);
|
|
5429
|
+
this.tab.activePane = panes[(idx + 1) % panes.length];
|
|
5430
|
+
}
|
|
5431
|
+
}
|
|
5432
|
+
|
|
5406
5433
|
async handlePrompt(text) {
|
|
5407
5434
|
const key = parseKey(text);
|
|
5408
5435
|
|
package/initramfs/lib/dlopen.js
CHANGED
|
@@ -119,12 +119,3 @@ export const withInetSocket = (use) => {
|
|
|
119
119
|
libc.symbols.close(fd);
|
|
120
120
|
}
|
|
121
121
|
};
|
|
122
|
-
|
|
123
|
-
// Renders /usr/share/doc/buninu-linux/<name>.md for --help. Hyperlinks are
|
|
124
|
-
// on so the references at the end of each page are clickable in terminals
|
|
125
|
-
// that support OSC 8.
|
|
126
|
-
export const showDocument = async (name) => {
|
|
127
|
-
const path = `${import.meta.dir}/../usr/share/doc/buninu-linux/${name}.md`;
|
|
128
|
-
const rendered = Bun.markdown.ansi(await Bun.file(path).text(), { hyperlinks: true });
|
|
129
|
-
process.stdout.write(rendered.endsWith("\n") ? rendered : `${rendered}\n`);
|
|
130
|
-
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Shared renderer for /usr/share/doc/buninu-linux/<name>.md command manuals.
|
|
2
|
+
export const showDocument = async (name) => {
|
|
3
|
+
const path = `${import.meta.dir}/../usr/share/doc/buninu-linux/${name}.md`;
|
|
4
|
+
const rendered = Bun.markdown.ansi(await Bun.file(path).text(), { hyperlinks: true });
|
|
5
|
+
process.stdout.write(rendered.endsWith("\n") ? rendered : `${rendered}\n`);
|
|
6
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Shared implementation for /bin/poweroff and /bin/reboot.
|
|
2
|
+
|
|
3
|
+
import { libc, check } from "./dlopen.js";
|
|
4
|
+
import { showDocument } from "./document.js";
|
|
5
|
+
|
|
6
|
+
export const LINUX_REBOOT_CMD_RESTART = 0x01234567;
|
|
7
|
+
export const LINUX_REBOOT_CMD_POWER_OFF = 0x4321fedc;
|
|
8
|
+
|
|
9
|
+
export const runPowerCommand = async ({ name, command, action }) => {
|
|
10
|
+
const arguments_ = process.argv.slice(2);
|
|
11
|
+
|
|
12
|
+
if (arguments_.length === 1 && (arguments_[0] === "-h" || arguments_[0] === "--help")) {
|
|
13
|
+
await showDocument(name);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (arguments_.length !== 0) {
|
|
18
|
+
console.error(`Usage: ${name} [-h | --help]`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.log(`${name}: syncing filesystems`);
|
|
23
|
+
libc.symbols.sync();
|
|
24
|
+
console.log(`${name}: ${action}`);
|
|
25
|
+
try {
|
|
26
|
+
check(`reboot(${command.name})`, libc.symbols.reboot(command.value));
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error(`${name}: ${error.message}`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// A successful reboot(2) never returns.
|
|
33
|
+
console.error(`${name}: reboot returned without ${action}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# ps — list processes
|
|
2
|
+
|
|
3
|
+
`/bin/ps` is a small Bun script that reads `/proc`. Its primary interface is
|
|
4
|
+
the full-command-line table consumed by bunmsh's `pspa` and coloured `pspac`
|
|
5
|
+
builtins.
|
|
6
|
+
|
|
7
|
+
The file is also an importable module. It exports `readProcessSnapshot()`,
|
|
8
|
+
`prepareProcessFormat()`, `formatProcessHeader()`, and
|
|
9
|
+
`formatProcessLine()`. `/bin/top` uses these exports, so process discovery and
|
|
10
|
+
single-row formatting have one implementation.
|
|
11
|
+
|
|
12
|
+
## Synopsis
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
ps
|
|
16
|
+
ps -e | -A [-o pid,args]
|
|
17
|
+
ps -eo pid,args
|
|
18
|
+
ps -ef | ps aux | ps ax
|
|
19
|
+
ps -h | --help # this page
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Options
|
|
23
|
+
|
|
24
|
+
| Option | Meaning |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `-e`, `-A`, `--all` | List every process instead of the default same-UID/same-TTY selection. |
|
|
27
|
+
| `-o FIELDS` | Select and order comma- or space-separated output fields. See below. |
|
|
28
|
+
| `-ef` | Full Unix view: UID, PID/PPID, CPU, start, TTY, accumulated time, and command. |
|
|
29
|
+
| `-eF` | Extra-full Unix view, adding `SZ`, `RSS`, and current processor (`PSR`). |
|
|
30
|
+
| `aux`, `-aux` | BSD view with user, CPU/memory percentages, VSZ/RSS, TTY, state, start, time, and command. |
|
|
31
|
+
| `ax`, `-ax` | Compact BSD view with PID, TTY, state, time, and command. |
|
|
32
|
+
| `-h`, `--help` | Render this page. |
|
|
33
|
+
|
|
34
|
+
`-e` and `-o` may be combined as `-eo pid,args`, which is the form bunmsh
|
|
35
|
+
uses. Rows are sorted numerically by PID. A process with an empty cmdline is
|
|
36
|
+
shown using its `/proc/PID/comm` name in brackets, as for a kernel thread.
|
|
37
|
+
With no `-o` or extended view, the standard columns are `PID TTY TIME CMD`,
|
|
38
|
+
and `CMD` is the short process name. The default selection is the caller's
|
|
39
|
+
effective UID and terminal, excluding session leaders. `-e`/`-A` selects all;
|
|
40
|
+
`a`, `x`, `-a`, and `-x` apply their usual BSD or Unix selection rules.
|
|
41
|
+
|
|
42
|
+
Plain `ps` excludes processes carrying Linux's `PF_KTHREAD` flag. This matters
|
|
43
|
+
on boot consoles where the shell and kernel threads may all be UID 0 without a
|
|
44
|
+
controlling TTY. Explicit all-process forms such as `ps -e`, `ps -A`, and
|
|
45
|
+
`ps -eo ...` include kernel threads.
|
|
46
|
+
|
|
47
|
+
### `-o` fields
|
|
48
|
+
|
|
49
|
+
Supported names are:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
pid ppid uid user euser comm args cmd command tty tt stat state c
|
|
53
|
+
%cpu pcpu %mem pmem vsz rss sz time etime etimes
|
|
54
|
+
start stime lstart ni nice pri psr
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
They may be combined and reordered, for example:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
ps -eo pid,ppid,user,comm
|
|
61
|
+
ps -eo pid,stat,%cpu,%mem,rss,args
|
|
62
|
+
ps -o pid,tty,time,comm
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`comm` is the kernel's short process name; `args` is the complete command
|
|
66
|
+
line. The exact `pid,args` layout remains the interface consumed by bunmsh.
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
ps
|
|
72
|
+
ps -eo pid,args
|
|
73
|
+
ps -ef # common LLM/tutorial spelling
|
|
74
|
+
ps aux
|
|
75
|
+
pspac # bunmsh: the same table with syntax colours
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Limits
|
|
79
|
+
|
|
80
|
+
Values come from `/proc/PID/stat`, `/proc/PID/status`, `/proc/uptime`, and
|
|
81
|
+
`/proc/meminfo`; user names come from `/etc/passwd`. CPU percentages are the
|
|
82
|
+
process's average since it started, and memory percentage is resident memory
|
|
83
|
+
over `MemTotal`. Forest display, custom column headings, and less common
|
|
84
|
+
procps fields remain outside this minimal command. `/proc` must be mounted.
|
|
85
|
+
|
|
86
|
+
## Exit status
|
|
87
|
+
|
|
88
|
+
`0` success, `1` bad usage or `/proc` could not be read.
|
|
89
|
+
|
|
90
|
+
## See also
|
|
91
|
+
|
|
92
|
+
- `ip --help`
|
|
93
|
+
- Source: `initramfs/bin/ps` in
|
|
94
|
+
[buninu-linux](https://github.com/jjtseng93/buninu-linux)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# reboot — restart Buninu Linux
|
|
2
|
+
|
|
3
|
+
`reboot` flushes pending filesystem writes with `sync(2)`, then requests
|
|
4
|
+
`LINUX_REBOOT_CMD_RESTART` through Linux `reboot(2)`. It shares its
|
|
5
|
+
implementation with `poweroff` and does not invoke a service manager.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
reboot
|
|
11
|
+
reboot --help
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The caller needs the kernel's `CAP_SYS_BOOT` capability. Buninu's root shell
|
|
15
|
+
has it; otherwise the command reports `Operation not permitted` and exits.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# tar — create and extract archives
|
|
2
|
+
|
|
3
|
+
`/bin/tar` is a small Bun script over `Bun.Archive`. It handles uncompressed
|
|
4
|
+
tar archives plus gzip and zstd without invoking another program.
|
|
5
|
+
|
|
6
|
+
## Synopsis
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
tar -cf ARCHIVE FILE...
|
|
10
|
+
tar -czf ARCHIVE FILE...
|
|
11
|
+
tar --zstd -cf ARCHIVE FILE...
|
|
12
|
+
tar -xf ARCHIVE [-C DIR] [MEMBER...]
|
|
13
|
+
tar -tf ARCHIVE [MEMBER...]
|
|
14
|
+
tar -h | --help # this page
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Use `-` as ARCHIVE to read from standard input or write to standard output.
|
|
18
|
+
|
|
19
|
+
## Options
|
|
20
|
+
|
|
21
|
+
| Option | Meaning |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `-c` | Create an archive. |
|
|
24
|
+
| `-x` | Extract an archive. |
|
|
25
|
+
| `-t` | List archive members. |
|
|
26
|
+
| `-f ARCHIVE`, `--file=ARCHIVE` | Archive file, or `-` for standard input/output. |
|
|
27
|
+
| `-C DIR`, `--directory=DIR` | Read input files from DIR, or extract into DIR. |
|
|
28
|
+
| `-z`, `--gzip` | Create gzip-compressed tar, or explicitly identify gzip input. |
|
|
29
|
+
| `--zstd` | Create or read a zstd-compressed tar. A `.zst` or `.tzst` input is also detected by name. |
|
|
30
|
+
| `-v` | Print names while creating/extracting; with `-t`, also show each regular file's size and modification time. |
|
|
31
|
+
|
|
32
|
+
Short options can be combined, for example `-xzvf` or `-czf`.
|
|
33
|
+
For the traditional first option word, the leading hyphen is optional, so
|
|
34
|
+
`tar tf`, `tar xf`, and `tar cf` are equivalent to `tar -tf`, `tar -xf`, and
|
|
35
|
+
`tar -cf`.
|
|
36
|
+
|
|
37
|
+
## Examples
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
tar -czf source.tar.gz src README.md
|
|
41
|
+
tar -xzf source.tar.gz -C /tmp/source
|
|
42
|
+
tar -tf source.tar.gz
|
|
43
|
+
tar --zstd -cf backup.tar.zst home
|
|
44
|
+
tar --zstd -xf backup.tar.zst -C /mnt/restore
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Current Bun.Archive limits
|
|
48
|
+
|
|
49
|
+
Creation stores regular files only. Symbolic links are rejected rather than
|
|
50
|
+
silently archived as the wrong type; modes, ownership, hard links, and empty
|
|
51
|
+
directories are not preserved. Bun 1.4.3 also requires file contents to be
|
|
52
|
+
materialized in memory before archive creation.
|
|
53
|
+
|
|
54
|
+
Extraction restores directories and symbolic links, but Bun 1.4.3 skips hard
|
|
55
|
+
links. Listing and verbose extraction use `Archive.files()`, so they report
|
|
56
|
+
regular files only. Verbose listing can show their size and modification time,
|
|
57
|
+
but not the unavailable mode or owner. Bun provides gzip and zstd codecs but no xz or bzip2 codec,
|
|
58
|
+
so this command does not accept `.tar.xz` or `.tar.bz2`.
|
|
59
|
+
|
|
60
|
+
Appending with `-r`/`rvf` is not supported. `Bun.Archive` has no append API;
|
|
61
|
+
rebuilding an existing archive through `Archive.files()` would silently lose
|
|
62
|
+
its directories, links, ownership, and modes, so this command refuses instead.
|
|
63
|
+
|
|
64
|
+
## Exit status
|
|
65
|
+
|
|
66
|
+
`0` success, `2` bad usage or an archive/file operation failed.
|
|
67
|
+
|
|
68
|
+
## See also
|
|
69
|
+
|
|
70
|
+
- [Bun.Archive](https://bun.com/docs/runtime/archive)
|
|
71
|
+
- [tar(1)](https://man7.org/linux/man-pages/man1/tar.1.html)
|
|
72
|
+
- Source: `initramfs/bin/tar` in
|
|
73
|
+
[buninu-linux](https://github.com/jjtseng93/buninu-linux)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# top
|
|
2
|
+
|
|
3
|
+
`top` periodically reads the process snapshot exported by `/bin/ps`. Process
|
|
4
|
+
discovery and row formatting are shared with `ps`; `top` only calculates CPU
|
|
5
|
+
changes between refreshes, sorts rows, and redraws the screen.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
top
|
|
11
|
+
top -d 1
|
|
12
|
+
top -b -n 1
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- `-d SECONDS` sets the refresh interval (default: 3).
|
|
16
|
+
- `-n COUNT` exits after that many snapshots.
|
|
17
|
+
- `-b` uses batch output without terminal control sequences.
|
|
18
|
+
- `-h`, `--help` displays this document.
|
|
19
|
+
|
|
20
|
+
While running interactively, press `q` to quit, `P` to sort by CPU, `M` to
|
|
21
|
+
sort by memory, or `N` to sort by PID. The first screen shows the lifetime CPU
|
|
22
|
+
average available from `ps`; later screens show usage during the refresh
|
|
23
|
+
interval.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "buninu-linux",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "A Linux distribution running Bun as PID 1 with the Buninu userspace.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -37,6 +37,6 @@
|
|
|
37
37
|
"fetch": "./index.js -f",
|
|
38
38
|
"pack": "./index.js -b",
|
|
39
39
|
"start": "./index.js -r",
|
|
40
|
-
"check": "for f in ./index.js ./initramfs/init.js ./initramfs/lib/dlopen.js ./initramfs/lib/modprobe.js ./initramfs/bin/mount ./initramfs/bin/umount ./initramfs/bin/ip ./initramfs/bin/poweroff; do node --check \"$f\" || exit 1; done"
|
|
40
|
+
"check": "for f in ./index.js ./initramfs/init.js ./initramfs/lib/document.js ./initramfs/lib/dlopen.js ./initramfs/lib/modprobe.js ./initramfs/lib/power.js ./initramfs/bin/mount ./initramfs/bin/umount ./initramfs/bin/ip ./initramfs/bin/ps ./initramfs/bin/top ./initramfs/bin/poweroff ./initramfs/bin/reboot ./initramfs/bin/tar; do node --check \"$f\" || exit 1; done"
|
|
41
41
|
}
|
|
42
42
|
}
|