A helper class to construct shell commands in a way that allows printing them.
The goal is to make it easy to print commands that are being run by a program, in a way that makes it easy and safe for a user to copy-and-paste.
- Security — the printed commands should be possible to use in all shells without injection vulnerabilities.
- Fidelity — the printed command must match the arguments provided.
- Aesthetics — the command is pretty-printed to make it easy to read and to avoid escaping/quoting simple arguments where humans usually would not.
Point 1 is difficult, and maybe even impossible. This library will do its best, but what you don't know can hurt you.
Construct a command by providing a command string and a list of arguments. Each argument can either be an individual string, or a "pair" list containing two strings (usually a command flag and its argument). Pairs do not affect the semantics of the command, but they affect pretty-printing.
// example.ts
import { PrintableShellCommand } from "printable-shell-command";
export const command = new PrintableShellCommand("ffmpeg", [
["-i", "./test/My video.mp4"],
["-filter:v", "setpts=2.0*PTS"],
["-filter:a", "atempo=0.5"],
"./test/My video (slow-mo).mov",
]);
command.print();This prints:
ffmpeg \
-i './test/My video.mp4' \
-filter:v 'setpts=2.0*PTS' \
-filter:a atempo=0.5 \
'./test/My video (slow-mo).mov'import { PrintableShellCommand } from "printable-shell-command";
import { spawn } from "node:child_process";
const command = new PrintableShellCommand(/* … */);
const child_process = spawn(...command.toCommandWithFlatArgs()); // Note the `...`
// or directly
await command.spawn().success;
await command.spawnTransparently().success;
await command.spawnDetached().success;import { PrintableShellCommand } from "printable-shell-command";
import { spawn } from "bun";
const command = new PrintableShellCommand(/* … */);
await spawn(command.toFlatCommand()).exited;
// or directly
await command.bun.spawnBun().success;
await command.bun.spawnBunInherit().success;Any command or argument containing the following characters is quoted and escaped:
(space character)"(double quote)'(single quote)`(backtick)|$*?><()[]{}&\;#
Additionally, a command is escaped if it contains an =.
Escaping is done as follows:
- The command is single-quoted.
- Backslashes and single quotes are escaped.