API Reference
$.sync
Zx provides both synchronous and asynchronous command executions, returns ProcessOutput
or ProcessPromise
respectively.
const list = await $`ls -la`
const dir = $.sync`pwd`
$({...})
$
object holds the default zx configuration, which is used for all execution. To specify a custom preset use $
as factory:
const $$ = $({
verbose: false,
env: {NODE_ENV: 'production'},
})
const env = await $$`node -e 'console.log(process.env.NODE_ENV)'`
const pwd = $$.sync`pwd`
const hello = $({quiet: true})`echo "Hello!"`
Moreover, presets are chainable:
const $1 = $({ nothrow: true })
assert.equal((await $1`exit 1`).exitCode, 1)
const $2 = $1({ sync: true }) // Both {nothrow: true, sync: true} are applied
assert.equal($2`exit 2`.exitCode, 2)
const $3 = $({ sync: true })({ nothrow: true })
assert.equal($3`exit 3`.exitCode, 3)
$({input})
The input option passes the specified stdin
to the command.
const p1 = $({ input: 'foo' })`cat`
const p2 = $({ input: Readable.from('bar') })`cat`
const p3 = $({ input: Buffer.from('baz') })`cat`
const p4 = $({ input: p3 })`cat`
const p5 = $({ input: await p3 })`cat`
$({signal})
The signal option makes the process abortable.
const {signal} = new AbortController()
const p = $({ signal })`sleep 9999`
setTimeout(() => signal.abort('reason'), 1000)
$({timeout})
The timeout option makes the process autokillable after the specified delay.
const p = $({timeout: '1s'})`sleep 999`
The full options list:
interface Options {
cwd: string
ac: AbortController
signal: AbortSignal
input: string | Buffer | Readable | ProcessOutput | ProcessPromise
timeout: Duration
timeoutSignal: string
stdio: StdioOptions
verbose: boolean
sync: boolean
env: NodeJS.ProcessEnv
shell: string | boolean
nothrow: boolean
prefix: string
postfix: string
quote: typeof quote
quiet: boolean
detached: boolean
spawn: typeof spawn
spawnSync: typeof spawnSync
log: typeof log
kill: typeof kill
}
cd()
Changes the current working directory.
cd('/tmp')
await $`pwd` // => /tmp
Like echo
, in addition to string
arguments, cd
accepts and trims trailing newlines from ProcessOutput
enabling common idioms like:
cd(await $`mktemp -d`)
⚠️
cd
invokesprocess.chdir()
internally, so it does affect the global context. To keepprocess.cwd()
in sync with separate$
calls enable syncProcessCwd() hook.
fetch()
A wrapper around the node-fetch-native package.
const resp = await fetch('https://medv.io')
question()
A wrapper around the readline package.
const bear = await question('What kind of bear is best? ')
sleep()
A wrapper around the setTimeout
function.
await sleep(1000)
echo()
A console.log()
alternative which can take ProcessOutput.
const branch = await $`git branch --show-current`
echo`Current branch is ${branch}.`
// or
echo('Current branch is', branch)
stdin()
Returns the stdin as a string.
const content = JSON.parse(await stdin())
within()
Creates a new async context.
await $`pwd` // => /home/path
$.foo = 'bar'
within(async () => {
$.cwd = '/tmp'
$.foo = 'baz'
setTimeout(async () => {
await $`pwd` // => /tmp
$.foo // baz
}, 1000)
})
await $`pwd` // => /home/path
$.foo // still 'bar'
await $`node --version` // => v20.2.0
const version = await within(async () => {
$.prefix += 'export NVM_DIR=$HOME/.nvm; source $NVM_DIR/nvm.sh; nvm use 16;'
return $`node --version`
})
echo(version) // => v16.20.0
syncProcessCwd()
Keeps the process.cwd()
in sync with the internal $
current working directory if it is changed via cd().
import {syncProcessCwd} from 'zx'
syncProcessCwd()
syncProcessCwd(false) // pass false to disable the hook
This feature is disabled by default because of performance overhead.
retry()
Retries a callback for a few times. Will return after the first successful attempt, or will throw after specifies attempts count.
const p = await retry(10, () => $`curl https://medv.io`)
// With a specified delay between attempts.
const p = await retry(20, '1s', () => $`curl https://medv.io`)
// With an exponential backoff.
const p = await retry(30, expBackoff(), () => $`curl https://medv.io`)
spinner()
Starts a simple CLI spinner.
await spinner(() => $`long-running command`)
// With a message.
await spinner('working...', () => $`sleep 99`)
glob()
The globby package.
const packages = await glob(['package.json', 'packages/*/package.json'])
which()
The which package.
const node = await which('node')
If nothrow option is used, returns null if not found.
const pathOrNull = await which('node', { nothrow: true })
ps()
The @webpod/ps package to provide a cross-platform way to list processes.
const all = await ps.lookup()
const nodejs = await ps.lookup({ command: 'node' })
const children = await ps.tree({ pid: 123 })
const fulltree = await ps.tree({ pid: 123, recursive: true })
kill()
A process killer.
await kill(123)
await kill(123, 'SIGKILL')
tmpdir()
Creates a temporary directory.
t1 = tmpdir() // /os/based/tmp/zx-1ra1iofojgg/
t2 = tmpdir('foo') // /os/based/tmp/zx-1ra1iofojgg/foo/
tmpfile()
Temp file factory.
f1 = tmpfile() // /os/based/tmp/zx-1ra1iofojgg
f2 = tmpfile('f.txt') // /os/based/tmp/zx-1ra1iofojgg/foo.txt
f3 = tmpfile('f.txt', 'string or buffer')
minimist
The minimist package.
const argv = minimist(process.argv.slice(2), {})
argv
A minimist-parsed version of the process.argv
as argv
.
if (argv.someFlag) {
echo('yes')
}
Use minimist options to customize the parsing:
const myCustomArgv = minimist(process.argv.slice(2), {
boolean: [
'force',
'help',
],
alias: {
h: 'help',
},
})
chalk
The chalk package.
console.log(chalk.blue('Hello world!'))
fs
The fs-extra package.
const {version} = await fs.readJson('./package.json')
os
The os package.
await $`cd ${os.homedir()} && mkdir example`
path
The path package.
await $`mkdir ${path.join(basedir, 'output')}`
yaml
The yaml package.
console.log(YAML.parse('foo: bar').foo)