Skip to content

Commit

Permalink
support ports linux
Browse files Browse the repository at this point in the history
  • Loading branch information
sylc committed Feb 8, 2021
1 parent 63f74ab commit 9591cf9
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 41 deletions.
34 changes: 23 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
### Run directly

```
deno run --unstable --allow-run --allow-net https://x.nest.land/dkill@0.2.3/cli.ts
deno run --unstable --allow-run --allow-net https://x.nest.land/dkill@0.3.0/cli.ts
```

### Install

```
deno install --unstable --allow-run --allow-net https://x.nest.land/dkill@0.2.3/cli.ts
deno install --unstable --allow-run --allow-net https://x.nest.land/dkill@0.3.0/cli.ts
```

You can then access use it using command `dkill`
Expand All @@ -34,38 +34,50 @@ Usage: dkill <pid_name_port>
Kill any process by
- port: add a semicolon in front to define it as a port. ex: 'dkill :3000'
- pid: a valid integer. ex: 'dkill 12654'
- pid: a valid integer. ex: 'dkill 12654'
- process name: not implemented yet
Options:
-h, --help - Show this help.
-V, --version - Show the version number for this program.
-v, --verbose - Increase verbosity
-d, --dryrun - Dry run, List the pids that would have been killed. Does not kill anything
```

## Programatic Usage

mod.ts exports multiple functions
mod.ts exports multiple functions that can be used programmatically. Check
source code for info

- dkill
- port2pid
- killPids
- dkill(targets: { pids?: number[]; ports?: number[]; procs?: string[]; },
opts?: { verbose?: boolean, dryrun?: boolean })
- port2pid()
- killPids()

## Support

- Windows
- [x] port
- [x] pids
- [x] pid
- [ ] process
- Linux
- [ ] port
- [x] pids
- [x] port
- [x] pid
- [ ] process
- Mac
- [ ] port
- [ ] pids
- [ ] pid
- [ ] process

## TODOs

- [ ] provide process names killed
- [ ] kill by process name
- [ ] supply multiple values to cli in on go
- [ ] on linux check if `ss` is present.

## Inspiration

- nodejs [fkill-cli](https://www.npmjs.com/package/fkill-cli)
54 changes: 33 additions & 21 deletions cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,40 @@ await new Command()
- process name: not implemented yet`,
)
.arguments("<port_proc_pid>")
.option("-v, --verbose", "increase verbosity")
.action(async (opts: { verbose: boolean }, port_proc_pid: string) => {
const ports: number[] = [];
const pids: number[] = [];
const procs: string[] = [];
.option("-v, --verbose", "Increase verbosity")
.option(
"-d, --dryrun",
"Dry run, List the pids that would have been killed. Does not kill anything",
)
.action(
async (
opts: { verbose: boolean; dryrun: boolean },
port_proc_pid: string,
) => {
const ports: number[] = [];
const pids: number[] = [];
const procs: string[] = [];

// Check if port
if (port_proc_pid.startsWith(":")) {
const port = +port_proc_pid.slice(1);
if (!Number.isInteger(port)) {
console.log(`Invalid port number "port"`);
return;
// Check if port
if (port_proc_pid.startsWith(":")) {
const port = +port_proc_pid.slice(1);
if (!Number.isInteger(port)) {
console.log(`Invalid port number "port"`);
return;
}
ports.push(port);
} else if (Number.isInteger(+port_proc_pid)) {
// check if pid
pids.push(+port_proc_pid);
} else {
// must be a string
procs.push(port_proc_pid);
}
ports.push(port);
} else if (Number.isInteger(+port_proc_pid)) {
// check if pid
pids.push(+port_proc_pid);
} else {
// must be a string
procs.push(port_proc_pid);
}

await dkill({ ports, pids, procs }, { verbose: opts.verbose });
})
await dkill({ ports, pids, procs }, {
verbose: opts.verbose,
dryrun: opts.dryrun,
});
},
)
.parse(Deno.args);
17 changes: 13 additions & 4 deletions src/dkill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export async function dkill(
ports?: number[];
procs?: string[];
},
opts?: { verbose?: boolean },
opts?: { verbose?: boolean; dryrun?: boolean },
) {
let pidsKilled: number[] = [];

Expand All @@ -18,7 +18,10 @@ export async function dkill(

// pids
if (pids && pids.length) {
const killed = await KillPids(pids);
let killed = pids;
if (!opts?.dryrun) {
killed = await KillPids(pids);
}
pidsKilled = pidsKilled.concat(killed);
}

Expand All @@ -30,7 +33,10 @@ export async function dkill(
verbose(`pids for port ${port}: ${pidsOfPort}`);
pidsOfAllPorts = pidsOfAllPorts.concat(pidsOfPort);
}
const killed = await KillPids(pidsOfAllPorts);
let killed = pidsOfAllPorts;
if (!opts?.dryrun) {
killed = await KillPids(pidsOfAllPorts);
}
pidsKilled = pidsKilled.concat(killed);
}

Expand All @@ -41,7 +47,10 @@ export async function dkill(
}

if (pidsKilled.length) {
console.log("pids Killed", pidsKilled);
console.log(
`${opts?.dryrun ? "list of pids target (not killed):" : "pids killed:"}`,
pidsKilled.join(" "),
);
} else {
console.log("No process found");
}
Expand Down
53 changes: 49 additions & 4 deletions src/port2pid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export async function port2pid(port: number): Promise<number[]> {
});

const out = await cmd.output();
cmd.close();
const outString = new TextDecoder().decode(out);
// outstring example
// TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 28392
Expand All @@ -20,16 +21,60 @@ export async function port2pid(port: number): Promise<number[]> {

const pidColumnsIndex = 4;

cmd.close();
const pids = parsedLines
.filter((arr) => arr.length !== 0) // filter last line
.map((arr) => +arr[pidColumnsIndex]) // extract pids based on columns
.filter((pid) => Number.isInteger(pid) && pid !== 0); // ensure they are numbers. port 0 can be ignored
.filter((pid) => Number.isInteger(pid) && pid !== 0); // ensure they are numbers. pid 0 can be ignored

return [...new Set(pids)]; // remove duplicates;
} else if (os === "linux") {
console.log("Platform not supported yet");
throw Error("Platform not supported yet");
const cmd = Deno.run({
// -l: listening
// -p: provide pid
// -n: provide local address
cmd: ["ss", "-lnp"],
stdout: "piped",
stderr: "piped",
});

const out = await cmd.output();
cmd.close();
const outString = new TextDecoder().decode(out);

// outstring example
// tcp LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("deno", pid=200, fd=12))
const parsedLines = outString
.split("\n")
.map((line) => line.match(/\S+/g) || []);

// parsedLines
// [ [ "LISTEN", "0", "128", "0.0.0.0:8080", "0.0.0.0:*", users:(("deno", pid=200, fd=12)) ], [] ]

const portColumnIndex = 4;
const pidColumnsIndex = 6;

// remove first row of titles
parsedLines.shift();

const pids = parsedLines
.filter((arr) => arr.length !== 0) // filter last line
.filter((arr) => {
const localAddrArr = arr[portColumnIndex].split(":");
return localAddrArr.length > 0 ? +localAddrArr[1] === port : false;
}) // filter connection for the targetted port
.map((arr) => {
// arr[pidColumnsIndex] should be like:
// users:(("deno", pid=200, fd=12))
const strArr = arr[pidColumnsIndex].match(/pid=(.*?),/);
if (!strArr) {
console.log("Line with issues", arr);
throw Error("Invalid parsing");
}
return +strArr[1];
}) // extract pids based on columns
.filter((pid) => Number.isInteger(pid) && pid !== 0); // ensure they are numbers. pid 0 can be ignored

return [...new Set(pids)]; // remove duplicates;
} else {
console.log("Platform not supported yet");
throw Error("Platform not supported yet");
Expand Down
16 changes: 16 additions & 0 deletions src/tests/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* webserver.ts
*/
import { serve } from "https://deno.land/std@0.86.0/http/server.ts";

const server = serve({ hostname: "0.0.0.0", port: 8080 });
console.log(`HTTP webserver running on port :8080`, Deno.build.os);

for await (const request of server) {
let bodyContent = "Your user-agent is:\n\n";
bodyContent += request.headers.get("user-agent") || "Unknown";

request.respond({ status: 200, body: bodyContent });
}

// deno -A ./src/tests/utils
2 changes: 1 addition & 1 deletion version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const version = "0.2.3";
export const version = "0.3.0";

0 comments on commit 9591cf9

Please sign in to comment.