zx
Google zx を用いて、JavaScript/TypeScript でより良いシェルスクリプトを作成、デバッグ、リファクタリングするための包括的なガイドを提供するSkill。
📜 元の英語説明(参考)
Comprehensive guide for writing shell scripts with Google zx — a tool for writing better scripts using JavaScript/TypeScript. Use when writing, debugging, or refactoring zx scripts (.mjs, .js, .ts files using zx), executing shell commands from JavaScript, working with ProcessPromise/ProcessOutput APIs, piping streams, configuring zx options, or using zx CLI. Do NOT use for general Node.js questions unrelated to shell scripting.
🇯🇵 日本人クリエイター向け解説
Google zx を用いて、JavaScript/TypeScript でより良いシェルスクリプトを作成、デバッグ、リファクタリングするための包括的なガイドを提供するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o zx.zip https://jpskill.com/download/5617.zip && unzip -o zx.zip && rm zx.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/5617.zip -OutFile "$d\zx.zip"; Expand-Archive "$d\zx.zip" -DestinationPath $d -Force; ri "$d\zx.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
zx.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
zxフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-17
- 取得日時
- 2026-05-17
- 同梱ファイル
- 5
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
[Skill 名] zx
Zx — JavaScript でより良いシェルスクリプトを書く
概要
zx は、Google が JavaScript/TypeScript でシェルスクリプトを書くために開発したツールです。child_process をラップし、引数を自動エスケープし、適切なデフォルト値を提供することで、スクリプト内で JavaScript エコシステムの力を活用できます。
#!/usr/bin/env zx
await $`cat package.json | grep name`
const branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`
const name = 'foo & bar'
await $`mkdir /tmp/${name}` // 引用符は不要 — 自動エスケープされます
Bash は簡単なタスクには優れていますが、スクリプトが複雑になると、本格的なプログラミング言語が役立ちます。zx は child_process の周りに便利なラッパーを追加し、引数をエスケープし、適切なデフォルト値を提供します。考えてみてください: bash と JavaScript が一つのスクリプトに。
トリガー
ユーザーが JavaScript でシェルコマンドを実行すること、bash スクリプトを zx に変換すること、リモートスクリプト、Markdown スクリプト、または TypeScript シェルスクリプトの実行について尋ねた場合にもトリガーされます。
クイックスタート
npm install zx
スクリプトを .mjs ファイルとして記述します(トップレベルの await をサポートします)。#!/usr/bin/env zx シバンを追加するか、CLI 経由で実行します。
zx ./script.mjs # 直接実行
npx zx ./script.mjs # npx 経由
node --import zx/globals # Node.js ローダーとして
すべての関数($, cd, fetch など)は、インポートなしで zx スクリプト内でグローバルに利用できます。明示的なインポート(VS Code のオートコンプリートが向上します)には、以下を使用します。
import 'zx/globals'
コアコンセプト
$`command` — シェルコマンドの実行
タグ付きテンプレートリテラルは zx の核心です。${...} 内のすべては自動的にエスケープされ、引用符で囲まれます。
// 非同期 (標準) — ProcessPromise を返します
const output = await $`ls -la`
// 同期バリアント — ProcessOutput を直接返します
const dir = $.sync`pwd`
// 配列はフラット化されます
const flags = ['--oneline', '--decorate', '--color']
await $`git log ${flags}`
// ゼロ以外の終了コードは ProcessOutput をスローします
try {
await $`exit 1`
} catch (p) {
console.log(`Exit: ${p.exitCode}, Error: ${p.stderr}`)
}
$({...}) を使用したプリセット設定
プリセットオプションを使用してカスタム $ インスタンスを作成します — チェーン可能で構成可能です。
const $$ = $({ verbose: false, env: { NODE_ENV: 'production' } })
const pwd = $$.sync`pwd`
// プリセットはチェーン可能です
const $1 = $({ nothrow: true })
const $2 = $1({ sync: true }) // nothrow と sync の両方が適用されます
ProcessPromise と ProcessOutput
$`cmd` ProcessPromise (Promise を拡張)
├── .pipe() ストリームパイピング
├── .kill() プロセスの終了
├── .text() 文字列としての出力
├── .json() パースされた JSON としての出力
├── .lines() 行で分割された出力
├── .nothrow() このコマンドのエラーを抑制
├── .quiet() このコマンドの出力を抑制
├── .timeout() 指定期間後に自動終了
├── .stdio() I/O の設定
├── .exitCode Promise<終了コード>
├── .stdout 読み取り可能ストリーム
├── .stderr 読み取り可能ストリーム
├── .stdin 書き込み可能ストリーム
├── .pid / .cmd プロセスメタデータ
└── await → ProcessOutput
├── .stdout string
├── .stderr string
├── .exitCode number
├── .signal string|null
├── .text() / .json() / .lines() / .buffer() / .blob()
└── .ok boolean (nothrow の場合)
意思決定ツリー
zx スクリプトを作成する際には、この意思決定ツリーを使用してください。
| 目標 | アプローチ |
|---|---|
| コマンドを実行する | await $`cmd` |
| 同期的に実行する | $.sync`cmd` |
| 出力をパイプする | .pipe($`next`) / .pipe('file.txt') |
| エラーを適切に処理する | $({nothrow: true}) / .nothrow() |
| タイムアウトを設定する | $({timeout: '30s'}) / .timeout('30s') |
| JSON 出力をパースする | (await $`cmd`).json() |
| リアルタイムストリーミング | for await (const line of $`cmd`) |
| 失敗時にリトライする | retry(5, () => $`cmd`) |
| ユーザープロンプト | question('Name: ') |
| 進捗インジケーター | await spinner('Working...', () => $`cmd`) |
| ディレクトリを変更する | cd('/path') または within(() => { $.cwd = '/tmp' }) |
| 一時ファイル/ディレクトリ | tmpfile() / tmpdir() |
| CLI 引数をパースする | argv.flag または minimist(process.argv.slice(2)) |
| .env ファイルをロードする | dotenv.config('.env') |
効果的な zx スクリプトの書き方
並列実行
const results = await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])
nothrow を使用したエラーハンドリング
$.nothrow = true
const repos = ['zx', 'webpod']
const clones = repos.map(n => $`git clone https://github.com/google/${n}`)
const results = await Promise.all(clones)
const errors = results.filter(o => !o.ok).map(o => o.stderr.trim())
console.log('Errors:', errors.join('\n'))
ストリームパイピング
// bash パイプのようにコマンドを連結します
const greeting = await $`printf "hello"`
.pipe($`awk '{printf $1", world!"}'`)
.pipe($`tr '[a-z]' '[A-Z]'`)
// ファイルにパイプします
await $`echo "Hello!"`.pipe('/tmp/output.txt')
// リアルタイム出力をターミナルに表示します
await $`echo 1; sleep 1; echo 2; sleep 1; echo 3`.pipe(process.stdout)
ストリームの分割と結合
// 一つのソースを複数のコンシューマーに分割します
const p = $`some-command`
const [o1, o2] = await Promise.all([
p.pipe`log`,
p.pipe`extract`,
])
// 複数のソースを結合します
const $h = $({ halt: true })
const p1 = $`echo foo`
const p2 = $h`echo a && sleep 0.1 && echo b`
const p3 = $h`echo c && sleep 0.1 && echo d`
const cat = $h`cat`
p1.pipe(cat); p2.pipe(cat); p3.pipe(cat)
await cat.run()
出力フォーマッター
const p = $`echo '{"foo":"bar"}\nline2'`
await p.json() // { foo: 'bar' }
await p.lines() // ['{"foo":"bar"}', 'line2']
await p.text() // '{"foo":"bar"}\nline2\n'
非同期イテレーション
for await (const line of $`g
(原文がここで切り詰められています) 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Zx — Write Better Shell Scripts with JavaScript
Overview
zx is Google's tool for writing shell scripts in JavaScript/TypeScript. It wraps child_process, auto-escapes arguments, and provides sensible defaults — giving you the power of the JavaScript ecosystem in your scripts.
#!/usr/bin/env zx
await $`cat package.json | grep name`
const branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`
const name = 'foo & bar'
await $`mkdir /tmp/${name}` // No quotes needed — auto-escaped
Bash is great for simple tasks, but when scripts grow complex, a full programming language helps. zx adds helpful wrappers around child_process, escapes arguments, and gives sensible defaults. Think: bash + JavaScript in one script.
Triggers
Also triggers when users ask about running shell commands in JavaScript, converting bash scripts to zx, executing remote scripts, Markdown scripts, or TypeScript shell scripts.
Quick Start
npm install zx
Write scripts as .mjs files (supports top-level await). Add #!/usr/bin/env zx shebang or run via CLI:
zx ./script.mjs # Direct execution
npx zx ./script.mjs # Via npx
node --import zx/globals # As Node.js loader
All functions ($, cd, fetch, etc.) are globally available in zx scripts without imports. For explicit imports (better VS Code autocomplete):
import 'zx/globals'
Core Concepts
$`command` — Execute Shell Commands
The tagged template literal is the heart of zx. Everything in ${...} is auto-escaped and quoted.
// Async (standard) — returns ProcessPromise
const output = await $`ls -la`
// Sync variant — returns ProcessOutput directly
const dir = $.sync`pwd`
// Arrays are flattened
const flags = ['--oneline', '--decorate', '--color']
await $`git log ${flags}`
// Non-zero exit codes throw ProcessOutput
try {
await $`exit 1`
} catch (p) {
console.log(`Exit: ${p.exitCode}, Error: ${p.stderr}`)
}
Preset Configuration with $({...})
Create custom $ instances with preset options — chainable and composable:
const $$ = $({ verbose: false, env: { NODE_ENV: 'production' } })
const pwd = $$.sync`pwd`
// Presets are chainable
const $1 = $({ nothrow: true })
const $2 = $1({ sync: true }) // Both nothrow + sync applied
ProcessPromise & ProcessOutput
$`cmd` ProcessPromise (extends Promise)
├── .pipe() Stream piping
├── .kill() Terminate process
├── .text() Output as string
├── .json() Output as parsed JSON
├── .lines() Output split by lines
├── .nothrow() Suppress errors for this command
├── .quiet() Suppress output for this command
├── .timeout() Auto-kill after duration
├── .stdio() Configure I/O
├── .exitCode Promise<exit code>
├── .stdout Readable stream
├── .stderr Readable stream
├── .stdin Writable stream
├── .pid / .cmd Process metadata
└── await → ProcessOutput
├── .stdout string
├── .stderr string
├── .exitCode number
├── .signal string|null
├── .text() / .json() / .lines() / .buffer() / .blob()
└── .ok boolean (when nothrow)
Decision Tree
When writing zx scripts, use this decision tree:
| Goal | Approach |
|---|---|
| Run a command | await $`cmd` |
| Run synchronously | $.sync`cmd` |
| Pipe output | .pipe($`next`) / .pipe('file.txt') |
| Handle errors gracefully | $({nothrow: true}) / .nothrow() |
| Set timeout | $({timeout: '30s'}) / .timeout('30s') |
| Parse JSON output | (await $`cmd`).json() |
| Real-time streaming | for await (const line of $`cmd`) |
| Retry on failure | retry(5, () => $`cmd`) |
| User prompt | question('Name: ') |
| Progress indicator | await spinner('Working...', () => $`cmd`) |
| Change directory | cd('/path') or within(() => { $.cwd = '/tmp' }) |
| Temp files/dirs | tmpfile() / tmpdir() |
| Parse CLI args | argv.flag or minimist(process.argv.slice(2)) |
| Load .env file | dotenv.config('.env') |
Writing Effective zx Scripts
Parallel Execution
const results = await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])
Error Handling with nothrow
$.nothrow = true
const repos = ['zx', 'webpod']
const clones = repos.map(n => $`git clone https://github.com/google/${n}`)
const results = await Promise.all(clones)
const errors = results.filter(o => !o.ok).map(o => o.stderr.trim())
console.log('Errors:', errors.join('\n'))
Stream Piping
// Chain commands like bash pipes
const greeting = await $`printf "hello"`
.pipe($`awk '{printf $1", world!"}'`)
.pipe($`tr '[a-z]' '[A-Z]'`)
// Pipe to file
await $`echo "Hello!"`.pipe('/tmp/output.txt')
// Real-time output to terminal
await $`echo 1; sleep 1; echo 2; sleep 1; echo 3`.pipe(process.stdout)
Stream Splitting & Merging
// Split one source to multiple consumers
const p = $`some-command`
const [o1, o2] = await Promise.all([
p.pipe`log`,
p.pipe`extract`,
])
// Merge multiple sources
const $h = $({ halt: true })
const p1 = $`echo foo`
const p2 = $h`echo a && sleep 0.1 && echo b`
const p3 = $h`echo c && sleep 0.1 && echo d`
const cat = $h`cat`
p1.pipe(cat); p2.pipe(cat); p3.pipe(cat)
await cat.run()
Output Formatters
const p = $`echo '{"foo":"bar"}\nline2'`
await p.json() // { foo: 'bar' }
await p.lines() // ['{"foo":"bar"}', 'line2']
await p.text() // '{"foo":"bar"}\nline2\n'
Async Iteration
for await (const line of $`git log --oneline --max-count=5`) {
console.log(line)
}
Shell Configuration
zx defaults to bash. Switch shells as needed:
import { useBash, usePowerShell, usePwsh } from 'zx'
usePowerShell() // PowerShell.exe
usePwsh() // PowerShell v7+
useBash() // Back to bash
// Manual override
$.shell = '/bin/zsh'
On Windows, consider using WSL or Git Bash for bash support, or switch to PowerShell via usePowerShell().
Built-in Helpers Summary
| Helper | Purpose | Example |
|---|---|---|
cd() |
Change directory | cd('/tmp') |
fetch() |
HTTP requests, supports .pipe() |
fetch('https://api.example.com') |
question() |
Interactive user input | question('Name: ') |
sleep() |
Delay execution | await sleep(1000) |
echo() |
Print to stdout | echo`Status: ${p}` |
stdin() |
Read stdin | JSON.parse(await stdin()) |
within() |
Isolated async config context | within(() => { $.cwd = '/tmp' }) |
retry() |
Retry with delay/backoff | retry(5, () => $curl url) |
spinner() |
CLI progress indicator | await spinner(() => $long-cmd) |
glob() |
File glob matching (globby) | glob('**/*.js') |
which() |
Find executable path | await which('node') |
ps |
Cross-platform process list | ps.lookup({ command: 'node' }) |
tmpdir() |
Temp directory | tmpdir('sub') |
tmpfile() |
Temp file | tmpfile('f.txt', 'content') |
argv |
Parsed CLI arguments | argv.verbose |
dotenv |
.env file loading | dotenv.config('.env') |
Exposed npm packages: chalk (colors), fs (fs-extra), os, path, YAML (yaml), minimist.
Resources
- references/api.md — Full API reference:
$options,cd(),fetch(),question(),sleep(),echo(),stdin(),within(),retry(),spinner(),glob(),which(),ps,kill(),tmpdir(),tmpfile(),minimist,argv,chalk,fs,os,path,YAML,dotenv,quote(),useBash(),usePowerShell(),usePwsh() - references/configuration.md — All
$.options:shell,prefix,postfix,quote,verbose,quiet,env,cwd,timeout,nothrow,detached,preferLocal,spawn,kill,log,input,signal,stdio,halt,delimiter,defaults - references/cli.md — CLI usage: flags, env vars, Markdown scripts, remote scripts, stdin execution, REPL mode
- references/process.md — ProcessPromise/ProcessOutput lifecycle, piping, killing, aborting, output formatters, stream handling
同梱ファイル
※ ZIPに含まれるファイル一覧。`SKILL.md` 本体に加え、参考資料・サンプル・スクリプトが入っている場合があります。
- 📄 SKILL.md (9,299 bytes)
- 📎 references/api.md (10,378 bytes)
- 📎 references/cli.md (3,982 bytes)
- 📎 references/configuration.md (4,516 bytes)
- 📎 references/process.md (6,649 bytes)