zx – bash scripts in javascript
Bash is widely used in programming and is an excellent tool, but it also has its drawbacks. Therefore, Google has developed a zx package that allows you to use bash inside javascript / typescript and has about 17k stars on github. This article will discuss the pros and cons of the library, the main aspects of use and examples of work.
The Node.js standard library provides bash scripting capabilities, but zx does a much better job. The package implements convenient asynchronous wrappers over child_procces, avoids multiple arguments, and also introduces basic bash commands like cd, pwd, and the like out of the box.
Features
- All functions ($, cd, fetch, etc.) are available immediately without any import.
- Executing the command returns
ProcessPromise<T>
- Node.js streams support
- Using
require()
in ESM modules - Automatic escaping of array data passed to the command
- Executing markdawn files
- Executing scripts over http
Application
For successful work, you should describe the script in the ESM module. This is required in order to use the operator await
immediately on the command being executed. If you need to use a regular .js / .ts file, then you need to wrap the functions in void async function () {...}()
…
In the first line of the file, add:
#!/usr/bin/env zx
To run it can be used like bash:
chmod +x ./script.mjs
./script.mjs
So zx:
zx ./script.mjs
To change the shell in which the script should run, you need to use the command $.shell
:
$.shell="/usr/bin/zsh"
In addition to using standard bash commands, you can write your own using zx. To do this, use a wrapper like await $`command`
which executes the described command. If the program terminates at zero, an object is returned. ProcessPromise<T>,
which has the following structure:
class ProcessPromise<T> extends Promise<T> {
readonly stdin: Writable
readonly stdout: Readable
readonly stderr: Readable
readonly exitCode: Promise<number>
pipe(dest): ProcessPromise<T>
}
Any other completion code throws an exception ProcessOutput
which has the following structure:
class ProcessOutput {
readonly stdout: string
readonly stderr: string
readonly exitCode: number
toString(): string
}
In the case when you need to find out what code a certain command returns, you can use the function notthrow()
, using which prevents throwing an exception and returns ProcessPromise<T>
…
Used packages
There are several packages included in zx that are available without import. One of them – chalk, it can be used to customize the style of text output to the terminal. Usage example:
console.log(chalk.purple('Hello world!'))
Also included a package fs to work with the file system.
let greetingMessage = await fs.readFile('./greetings.txt')
Package os provides work with the operating system.
await $`cd ${os.homedir()} && touch Documents/page1.txt`
Comparison with analogues
There is a project shellpy, which implements work with bash from python, but, unfortunately, a stable version has not been released, so using it in production is not a good idea. It is possible to use subprocess in python, but it is time consuming and does not provide the same usability as zx.
Java also has the ability to work with the shell, but there is no wrapper over the main commands, so all the logic has to be implemented using the language means, which is no longer the main goal of this article.
In addition, there are many languages in which you can work with bash, but it will take an extremely long time to describe them.
Output
zx is a powerful library for working with bash from javascript. The project is developed and supported by Google. It already implements the basic functions that can be used quickly and easily without self-written wrappers. In addition, all processes are executed asynchronously, which in most cases improves performance. And the very possibility of using bash in a high-level programming language makes it easy to write scripts to automate processes in the OS.
Advertising
Cloud hosting for business and any large projects – maximum configuration – 128 CPU cores, 512 GB RAM, 4000 GB NVMe, reliable data centers, protection against DDoS attacks “out of the box”, activation of any server within a minute!
Subscribe to our chat in Telegram…