Add metadata entry for list-ports.ts script in script-meta-v2.json and introduce new single script file list-ports.ts

This commit is contained in:
2026-04-18 20:53:56 +08:00
parent ba08f22029
commit 8e6b92fca9
2 changed files with 79 additions and 0 deletions

View File

@@ -223,6 +223,15 @@
"publish_time": 1737272626141,
"update_time": 1750472965160
},
"list-ports.ts": {
"script_name": "list-ports.ts",
"script_length": 2072,
"script_sha256": "2033072a42dd8b05576eaac9f41fa97deff5010726861ac217a1c74478a7ae6e",
"script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/single-scripts/list-ports.ts",
"single_script_file": true,
"publish_time": 1776516833640,
"update_time": 1776516833640
},
"lower.ts": {
"script_name": "lower.ts",
"script_length": 390,

70
single-scripts/list-ports.ts Executable file
View File

@@ -0,0 +1,70 @@
#!/usr/bin/env -S deno run --allow-all
const ttyProc = await Deno.run({
cmd: ["tput", "cols"],
stdout: "piped",
stderr: "piped",
});
const ttyOutput = new TextDecoder().decode(await ttyProc.output()).trim();
const terminalWidth = parseInt(ttyOutput) || 120;
const netstatProc = await Deno.run({
cmd: ["netstat", "-an"],
stdout: "piped",
stderr: "piped",
});
const output = await netstatProc.output();
const decoded = new TextDecoder().decode(output);
const lines = decoded.split("\n");
const localWidth = 20;
console.log("Active Internet connections (only servers)");
console.log(`Proto Recv-Q Send-Q Local Address${" ".repeat(localWidth - 13)}Foreign Address State PID/Program name`);
const listeningLines = lines.filter((line) => line.includes("LISTEN"));
const seen = new Set<string>();
for (const line of listeningLines) {
const parts = line.trim().split(/\s+/);
if (parts.length < 5) continue;
const proto = parts[0];
const localAddr = parts[3];
const state = parts[4];
const key = `${proto}:${localAddr}`;
if (seen.has(key)) continue;
seen.add(key);
const port = localAddr.includes(".")
? localAddr.split(".").pop()
: localAddr.split(":").pop();
const pidCmd = await Deno.run({
cmd: ["lsof", "-i", `:${port}`, "-t"],
stdout: "piped",
stderr: "piped",
});
const pidOutput = new TextDecoder().decode(await pidCmd.output()).trim();
let pidInfo = "-";
if (pidOutput) {
const pid = pidOutput.split("\n")[0];
const nameCmd = await Deno.run({
cmd: ["ps", "-p", pid, "-o", "args="],
stdout: "piped",
stderr: "piped",
});
const nameOutput = new TextDecoder().decode(await nameCmd.output()).trim();
pidInfo = nameOutput;
}
const displayState = state === "*.*" ? "LISTEN" : state;
const localFormatted = localAddr.padEnd(localWidth);
const recvQ = "0".padStart(3);
const sendQ = "0".padStart(6);
console.log(
`${proto.padEnd(8)} ${recvQ} ${sendQ} ${localFormatted} ${"0.0.0.0:*".padEnd(22)} ${displayState.padEnd(11)} ${pidInfo}`
);
}