UNPKG

@j-o-r/sh

Version:

Execute shell commands on Linux-based systems from javascript

177 lines (142 loc) 4.72 kB
# @j-o-r/sh Execute shell commands from JavaScript. ## Introduction `@j-o-r/sh` is a Node.js module that simplifies the execution of shell commands within JavaScript applications. It provides a range of utilities to handle shell scripts and manage their output efficiently. This project draws inspiration from the exceptional [zx library](https://github.com/google/zx). The core functionality of zx, particularly the shell execution method, has been extracted and forms the foundation of this project. ## Installation Install the module using npm: ```sh npm install @j-o-r/sh ``` ## Usage ### Basic Usage To execute a shell command, use the `SH` function: ```javascript import { SH, cd, within, sleep, retry, expBackoff } from '@j-o-r/sh'; SH`your_shell_command`.run() .then(output => { console.log('Output:', output); }) .catch(error => { console.error('Error:', error); }); ``` ### Advanced Usage ```javascript const res = await SH`ls -FLa | grep package.json | wc -l`.run(); console.log(res); const ar = within(async () => { const res = await Promise.all([ SH`sleep 1; echo 1`.run(), SH`sleep 2; echo 2`.run(), sleep(2), SH`sleep 3; echo 3`.run() ]); }); ``` ```javascript const p = await retry(3, expBackoff(), () => SH`curl -s https://unreachable`.run()); ``` The `SH` method accepts a template literal string enclosed in backticks as its argument. It returns an `SHDispatch` object. ### Additional Utilities The module also provides additional utilities for common tasks: - `parseArgs(process.args)`: Transform an array of strings into an object - `cd(dir)`: Change the working directory. - `sleep(duration)`: Pause execution for a specified duration. - `retry(count, interval, callback)`: Retry a command a specified number of times with an optional interval. - `readIn()`: Read from standard input. - `within(callback)`: Create an async context in a sync block. - `expBackoff(max, rand)`: Generate intervals for exponential backoff. - `jsType(any)`: Get the 'real' javascript variable type - `assert.`: Node assert library - `new Test()`: A small sync/async minimal test framework ## SHDispatch This class is returned by the `SH` function. Here's a summary of its methods and properties: ### Methods - **options(options)**: Sets options for the command execution. - **run(payload?)**: Executes the command and returns a promise that resolves with the command's output. - **runSync(payload?)**: Executes the command synchronously and returns a `SpawnSyncResponse`. - **kill()**: Sends a kill signal to the child process. ### Examples - Elementary usages, piped: ```javascript const res = await SH`ls -FLa | grep package.json | wc -l`.run(); console.log(res); ``` - Feed command with content: ```javascript const res = await SH`wc -l`.run(`one\ntwo\n`); console.log(res); ``` - Create a command from a string ```javascript const command = "uname -r"; const content = await SH`${command}`.run(); console.log(content); ``` - Async context with multiple commands and sleep: ```javascript within(async () => { const res = await Promise.all([ SH`sleep 1; echo 1`.run(), SH`sleep 2; echo 2`.run(), sleep(2), SH`sleep 3; echo 3`.run() ]); console.log(res); }); ``` - Retry with exponential backoff: ```javascript try { const p = await retry(3, expBackoff(), () => SH`curl -s https://flipwrsi`.run()); } catch (e) { console.error('Retry failed:', e); } ``` - Method for copying data to the clipboard: ```javascript /** * Copy text to the clipboard * @param {string} text * @returns {Promise<string>} */ const copyToClipboard = async (text) => { const prams = [ '-selection', 'clipboard' ] return SH`xclip ${prams}`.options({stdio: 'inherit'}).run(text); } ``` - Open the 'vim' editor ```javascript SH`vim`.options({stdio: 'inherit'}).runSync(); ``` - Create and run a test ```javascript import { assert, jsType, Test} from '@j-o-r/sh'; const test = new Test(); test.add('Test is test in sync', () => { assert.strictEqual(jsType(test), 'Test'); }); test.add('Test an Array in sync', () => { assert.strictEqual(jsType([]), 'Array'); }); test.add('Test is test in async', async () => { assert.strictEqual(jsType(test), 'Test'); }); test.add('Test is test in async, returning a promise', async () => { return new Promise((resolve, _reject) => { assert.strictEqual(jsType(test), 'Test'); resolve(); }); }); const report = await test.run(); if (report.errors > 0) { process.exit(1); } // await test.run([0,3]); // only run test 0 and 3 ``` ## License This project is licensed under the Apache License, Version 2.0.