8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

実行できて見栄えも良いMarkdown手順書で快適な運用ライフを送ろう!

8
Last updated at Posted at 2020-09-13

実行できる手順書(LC4RI)ってのご存じでしょうか?

ドキュメントとコマンドが混じって書いてあって、コマンド部分は実行できて、
その実行結果が載っています。
なので、手順書として読めて、かつ実行した内容とその時の出力がエビデンスとしてとれるもので
運用作業者にとってはExcel手順書の置き換えにぴったし
なんですね

そういう書き方が出来るツールとしてjupyter notebookが良く使われているんですけど、
これが運用してみるとドキュメントの並び替えとか、編集が意外と面倒だったりする。

もっと普通のエディタで書けたら・・そう思ってました。したらヒラめいた!

VSCodeのmarkdown編集機能を実行できるようにすれば良いんだ!!

つくってみたわ

lc4ri2.gif

VScodeのマーケットプレイスからインストールするならこちら

こっちGit。

つかいかた

基本は普通のmarkdownと同じ書きっぷりです。リスト水平線番号リストで変わります。

VSCodeのカーソル位置から下にあるコマンドを実行していきます
なので、実行したい部分までカーソルを持ってってこの拡張機能を動かしてください。
ショートカットキーに拡張機能の実行を割り当てると超便利ですよ!

リスト

1.png

実行したいコマンドを書きます。
タブでインデントをずらすとAND条件になります。
つまり、

    • ls existsfile.txt
      • - rm existsfile.txt

でexistsfile.txtが無ければ削除しない、みたいな書き方ができます。

水平線

2.png

3.png

コマンドの実行範囲を区切ります。区切らないとリスト表記のを上から順に実行しちゃいます。

番号リスト

4.png

変数をもてます1.~9.の範囲で実行結果の出力を変数として格納します
重いコマンドとか何度も実行したくないものは結果を格納して使いまわせます。

コンフィグファイル

以下のようなサンプルで設定ファイルを作れます(無ければ自動生成します)

{
  "timeout": 10000,
  "template": {
    "linux": "ssh user@192.168.0.1 {COMMAND}"
  },
  "changeWord": {
    "#HOME#": "/home/user"
  },
  "toutf8": true,
  "toterminal": true
}

timeout

タイムアウト時間です。実行する時間が長いものはタイムアウトするようになってます

template

OSの環境にあわせて各コマンドを実行するテンプレートを定義します。
例えばlinuxの環境だったら、全部SSH経由で実行するみたいな定義が出来ます

通常lsと書いた場合ローカルでlsコマンドを実行します
    - ls
ただ、定義をこのようにすると
    ssh user@192.168.0.1 "{COMMAND}"
全てSSH経由でリモート実行されるようになります
    ssh user@192.168.0.1 ls

chageWord

ワードで文字列変更します

元の文字がこうなってて
    - ls #HOME#
定義がこうなってると
    "#HOME#": "/home/user"
このように置き換えて実行されます
    ls /home/user

toutf8

デフォオン(true)で、falseにするとSJISのまま処理されるはずなんですが・・・なんか手元だとうまく動かないですね。。

toterminal

trueに設定するとターミナルで直接実行します。↑のオプションがうまく動かない時はこちらで・・・

v1.0: 大幅リファクタ — 新機能

1. CodeLens(コマンドラインの再実行ボタン)

リスト形式のコマンド行の左側に「▶ Run」「Dry-run」ボタンが表示されます。

- uname -a

カーソルを動かして全体実行を行わずに、そのコマンド行だけ実行したい時に便利です。"lc4ri.showCodeLens": falseで無効にできます。

2. settings.json対応(後方互換性あり)

拡張機能の設定がVS Codeのsettings.jsonから読み込まれるようになりました。従来の~/.code-lc4ri/config.jsonも引き続き使用可能です。

{
  "lc4ri.timeout": 15000,
  "lc4ri.profiles": {
    "prod-ssh": "ssh ops@prod.example.com {COMMAND}",
    "docker":   "docker exec -i app sh -c \"{COMMAND}\""
  },
  "lc4ri.changeWord": { "#HOME#": "/home/user" },
  "lc4ri.outputFormat": "collapsible",
  "lc4ri.confirmDangerous": true,
  "lc4ri.showCodeLens": true
}

3. 危険なコマンドの自動警告

実行コマンドが危険なパターン(rm -rf /dd if=など)に該当する場合、実行前に確認ダイアログが表示されます。

  • lc4ri.dangerousPatterns:警告を表示するコマンドパターン(正規表現)
  • lc4ri.denyList:実行を完全に禁止するコマンド
  • lc4ri.allowList:指定したコマンドのみ実行を許可

すべての実行コマンドはcode-lc4riの出力チャネルに記録されます。

4. 名前付き変数と組み込み変数

従来の{1}{9}に加えて、より柔軟な変数機能が追加されました。

構文 意味
1. コマンド → {変数名} コマンドの出力を{1}{変数名}の両方に格納
- コマンド → {変数名} リスト形式のコマンド出力を名前付き変数に格納
{$PREV} 前のコマンドの標準出力
{$STATUS} 前のコマンドの終了コード
{$DATE}{$CWD}{$USER}{$HOST} 実行時の環境値

5. アサーション機能(- assert: ...

コマンドの出力や終了コードを検証できます。

- curl -s http://api.local/health
    - assert: contains "ok"
    - assert: status == 0
    - assert: regex /version: \d+/

アサーション結果は出力ブロックに「✓ pass」「✗ FAIL」として記録されます。失敗するとAND-chainが中断されます。

6. ステータスバーのプロファイルスイッチャー

ステータスバーの右側にlc4ri: <プロファイル名>が表示され、クリックしてプロファイル(SSH、Docker、kubectlなど)を切り替えられます。ドキュメントを編集せずに実行環境を変更できます。

7. 実行レポートのエクスポート

実行セッション全体のレポートを生成できます。

  • code-lc4ri: Export execution report (HTML):実行結果を✓/✗付きで整形したHTML形式
  • code-lc4ri: Export execution report (Markdown):Markdown形式

運用作業のエビデンスやCI成果物として活用できます。

8. CLIランナー(ヘッドレス実行・CI対応)

VSCode拡張なしにMarkdownを実行できるCLIツールが提供されます。

npx code-lc4ri run runbook.md
npx code-lc4ri run runbook.md --dry-run
npx code-lc4ri run runbook.md --profile prod-ssh --report report.html

コマンドが失敗した場合、終了コードは0以外になるため、CI環境に直接組み込めます。

v1.1: 新機能

1. コマンド実行プレフィックス

プロンプトの先頭に記号を付けることで、実行方式を制御できます。

プレフィックス 動作
& <メッセージ> このターン内のBashコマンドをバックグラウンド実行
! <コマンド> ユーザーのターミナルで直接実行(出力をキャプチャしない)
なし 通常のフォアグラウンド実行(デフォルト)

2. .envファイルの読み込み

手順書のどこかに環境ファイルを指定すると、その中の環境変数を全コマンドで使用できます。

# env: .env.prod
- echo {DB_HOST}

3. 手順書のインクルード

別のMarkdownファイルを埋め込んで実行できます。インクルードされたファイル内で定義された変数は親スコープに引き継がれます。

- include: setup.md
- echo セットアップ完了

4. 並列実行

[parallel]プレフィックスを付けたコマンド行は、グループ化されて同時実行されます。

- [parallel] ssh server1 uptime
- [parallel] ssh server2 uptime
- [parallel] ssh server3 uptime

全コマンドが成功してはじめてAND-chainが続きます。1つでも失敗すると中断されます。

5. ファイルオープンとターミナル送信

記法 動作
- ! path.md / - open: path.md ファイルを新規タブで開く
- ! コマンド アクティブなターミナルに送信(出力キャプチャなし)

6. インデント仕様の改善

DEFAULT_INDENT_SPACESが4から2スペースに変更されました。これにより、Markdown標準の2スペースインデントが正しくAND-chain深度にマップされます。

- echo a       ← 深度0:常に実行
  - echo b     ← 深度1:aが成功したら実行
    - echo c   ← 深度2:bが成功したら実行
- echo d       ← 深度0:常に実行

従来の4スペースインデントを使いたい場合は、"lc4ri.tabWidth": 4で復帰できます。

7. write:ディレクティブ

手順書からファイルに内容を直接書き込めます。

- write: output/config.yaml
  ```yaml
  database:
    host: localhost
    port: 5432
  ```
  • フェンスブロック内のコンテンツが指定パスに書き込まれます
  • ファイルパスに変数置換が適用されます
  • 親ディレクトリが存在しない場合は自動作成されます
  • AND-chain に参加するため、インデント内のwrite:は親コマンドの成功時のみ実行されます
  • --dry-runで実際の書き込みをせずに解決後のパスと内容を確認できます

v1.2: 新機能

1. 対話入力(prompt:ディレクティブ)

実行を一時停止してユーザーに値の入力を求め、答えを名前付き変数に格納できます。

- prompt: {TARGET_HOST} 接続先のホスト名を入力してください
- ssh {TARGET_HOST} uptime

image.png

カーソル位置のAND-chainルールが適用されるため、インデントされたprompt:は親コマンドが成功した場合のみ発動します。

書き方

- prompt: {変数名} <ユーザーに表示するメッセージ>
オプション 説明
(なし) - prompt: {NAME} 名前を入力 入力ボックスを表示し、入力テキストを{NAME}に格納
secret - prompt: secret {PASS} パスワードを入力 マスク入力(パスワード欄)になります

ユーザーが何も入力せずダイアログを閉じた場合、AND-chainが中断され、出力ブロックに(cancelled by user)と記録されます。

dry-run時はダイアログが表示されず、出力ブロックに[dry-run] would prompt: <メッセージ>と記録されるので、副作用なしに変数名とメッセージを確認できます。

使用例

1. hostname → {host}
- prompt: {DEPLOY_ENV} デプロイ先の環境を入力してください(staging/prod)
- echo deploying {host} → {DEPLOY_ENV}

2. リトライ/待機ディレクティブ

[retry: N]プレフィックスをリストコマンドに付けると、コマンドが0以外の終了コードで終わった場合に最大N回再実行されます。

書き方

- [retry: <回数>] コマンド
- [retry: <回数>, <間隔>] コマンド
- [retry: <回数>, interval: <間隔>] コマンド
パーツ 説明
count [retry: 5] 最大リトライ回数(合計試行回数 = 回数 + 1)
interval(ms) [retry: 3, 500] リトライ間に500ミリ秒待機
interval(s) [retry: 3, 2s] リトライ間に2秒待機

単位サフィックスは省略可能で、数値のみの場合はミリ秒として扱われます。

動作の詳細:

  • いずれかの試行でコマンドが**成功(exit 0)**した場合、即座にリトライを停止してAND-chainを継続します
  • 全試行が失敗した場合は通常と同様にAND-chainが中断されます
  • 各待機期間は出力ブロックに[retry N/M wait Xms...]として記録されるのでログが自明になります
  • プログレストーストにはリトライ中command (try N)と表示されます
  • [parallel]との組み合わせも対応しており、順番はどちらでもOKです

使用例

- [retry: 3] curl -sf http://api.local/health
    - echo service is up

- [retry: 5, 2s] kubectl rollout status deployment/app

ヘルスチェックが通るまで2秒間隔でリトライする例:

- [retry: 10, interval: 2s] curl -sf http://db:5432/ready
    - echo database is ready
    - [retry: 3, 500] psql -c "SELECT 1"

3. リアルタイム出力ストリーミング

コマンドの出力がMarkdownドキュメントに逐次反映されるようになりました。コマンドが終了してから一括表示ではなく、ログのtailやビルドスクリプト、テスト実行など時間のかかるコマンドで特に便利です。

どうやって動いてるの?

  • 200ミリ秒間隔のタイマーが蓄積されたstdout/stderrのチャンクをコマンド下の出力コードブロックへ書き出します
  • 出力ブロックが存在しない場合は最初のフラッシュ時に自動生成されます
  • 追記ではなくブロックを上書き更新するので、ドキュメントがきれいに保たれます
  • runLines完了後にも最終同期が走り、最後のチャンクが確実に書き込まれます
  • [stderr]行にはプレフィックスが付くのでstdoutと視覚的に区別できます

設定不要

ストリーミングは常時有効です。追加設定は必要ありません。

他の機能との組み合わせ

機能 ストリーミング時の動作
Retry 各試行の出力がリアルタイムに追記され、[retry N/M wait Xms...]マーカーも次の試行前にリアルタイムで表示されます
Cancel プログレストーストのCancelをクリックすると子プロセスが停止し、すでにストリームされた内容はドキュメントに残ります
collapsible出力形式 <details>ラッパーが最初のフラッシュ時に書き込まれ、以降のフラッシュでもインプレース更新されます
toterminal 出力はターミナルに送られると同時に、ドキュメントにもストリームバックされます

v1.3: コードブロック実行とauto-write

1. bash/sh/zshブロックをそのまま実行

フェンスつきコードブロックの内容を、各行に-を付けなくても直接実行できるようになりました。長いシェルスクリプトを書くときにとても便利です。

ブロック内の変数({変数名})は解決され、行継続(\)も自動サポートされます。ブロック内のいずれかのコマンドが失敗すると、そこで実行を即時停止します。

```bash
echo "依存関係をインストール中..."
curl -sL http://api.local/tarball.gz | tar -xz \
    -C /opt/app \
    --strip-components=1
echo "完了!"
```

2. yaml/conf/jsonブロックの自動書き出し

設定ファイル用のフェンスつきコードブロック(yaml、conf、json)が自動検出され、ディスクに保存されます。スペースを空けてファイル名を指定できます。

```yaml config/settings.yml
database:
  host: {DB_HOST}
  port: 5432
```

フェンス定義にファイル名を省略した場合、code-lc4riがユニークな英数字ファイル名(例:gHJkLmNa.yaml)を自動生成し、出力ブロックにどのファイルが生成されたかを記録します。

```json
{
  "status": "ready",
  "enabled": true
}
```

v1.4: 新機能

既存のドキュメントや設定はそのままで使い続けられます。実行の可視化・デバッグに役立つ4つの新しいパネルとツールが追加されました。

1. 変数インスペクターパネル

image.png

現在のセッションのすべての変数を一覧できるライブサイドパネルです。

開き方: コマンドパレット → code-lc4ri: Show Variable Inspectorextension.lc4ri.showVarInspector)、またはキーバインドを設定。

パネルはアクティブエディタの横に開き、コマンドの実行に合わせてリアルタイムに同期されます。4つのセクションに分かれています:

セクション 内容
番号変数 {1}{9}と現在の値
名前付き変数 → {名前}prompt:で束縛されたすべての{名前}
組み込み値 {$PREV}{$STATUS}{$CWD}がリアルタイムに更新
環境変数(セッション) export:または.env読み込みで注入された変数

上部のフィルターボックスで名前をタイプするとリストをすぐに絞り込めます。長い値はmore / lessトグルで折りたたみ表示されます。右上のタイムスタンプはパネルの最終更新時刻を示します。

コマンド実行後とprompt:入力後に自動更新されるので、パネルを開き直す必要はありません。

2. 実行履歴ブラウザー

VSCodeを離れずに過去の実行セッションを閲覧・検索・確認できます。

開き方: コマンドパレット → code-lc4ri: Show Execution Historyextension.lc4ri.showHistory)。

記録される内容

Run from cursorまたは▶ Run(CodeLens)が実行されるたびに新しいセッションが作成されます。実行終了後、セッションはワークスペースルート(ワークスペースが開いていない場合は$HOME)の**.lc4ri-history.jsonに保存されます。最大50セッション**が保持され、古いセッションは自動で削除されます。

各セッションには以下が記録されます:

  • 手順書のファイル名、開始/終了タイムスタンプ、アクティブなプロファイル
  • コマンドごと:コマンドテキスト、終了コード、所要時間、成否フラグ

パネルの使い方

  • セッション行を展開/折りたたみして個別コマンドを確認できます
  • 検索ボックスで全セッションのコマンドテキストを横断検索できます
  • ステータスフィルター全て / ✅ 成功のみ / ❌ 失敗のみ)で結果を絞り込めます
  • セッション行のTimelineをクリックすると、そのセッションのウォーターフォールビューが開きます(機能4参照)
  • Clear Allをクリックすると履歴ファイルを消去してリストをリセットします

コマンド一覧

コマンド 説明
extension.lc4ri.showHistory 履歴ブラウザーパネルを開く
extension.lc4ri.clearHistory 保存済みの全履歴を消去する

3. 出力ブロック検索

コマンドに続く出力コードブロックの中をインラインハイライトと前後ナビゲーションで検索できます。Markdownファイルを離れずに使えます。

使い方:

  • 出力コードブロック(``````)の上に表示される🔍 Search output CodeLensをクリック、または
  • カーソルを出力ブロックの上か内側に置いた状態でcode-lc4ri: Search Output Blockextension.lc4ri.searchOutput)をコマンドパレットから実行。

入力ボックスが表示されるのでキーワードを入力してEnterを押します。

動作の詳細:

  • すべてのマッチはVS Codeの標準の検索マッチ色でハイライトされます
  • 現在のマッチは明るい色、他はグレーアウトされます
  • "キーワード" — N/M matchesという情報トーストにNext ↓Prev ↑ボタンが表示され、各マッチを順番に確認できます
  • Clearをクリックする(またはトーストを閉じる)とすべてのデコレーションが消えます
  • キーワードが見つからない場合は警告メッセージが表示され、デコレーションは適用されません

CodeLensとの統合:

🔍 Search output🗑 Clearレンズが出力ブロックの開始フェンス行に表示されます。既存の▶ RunDry-runレンズと並んで表示され、"lc4ri.showCodeLens": falseでまとめて無効にできます。

🔍 Search output  🗑 Clear
[ ls -la ] Mon Jun 01 14:32:00 2026
total 48
drwxr-xr-x 12 user user 4096 ...

4. 実行タイムライン(ウォーターフォール)

image.png

セッション内の全コマンドの所要時間と順序をインタラクティブなウォーターフォールチャートで可視化します。

開き方:

  • コマンドパレット → code-lc4ri: Show Execution Timelineextension.lc4ri.showTimeline)で現在のセッションを表示
  • 履歴ブラウザーの任意のセッション行のTimelineをクリックで過去のセッションを表示

チャートの見方

各コマンドは横棒で表示されます。棒はコマンドの開始時刻から終了時刻まで、セッション開始からの相対時間で描画されます。

意味
🟢 ティール 通常(順次)コマンド、exit 0
🔵 ブルー 並列コマンド([parallel])、exit 0
🔴 レッド 失敗したコマンド(終了コード ≠ 0)
グレー背景 並列グループ(Promise.allで実行されたコマンド群)

並列グループは全コマンドにまたがる半透明のボックスで示され、ツールチップにグループ番号が表示されます。

ツールチップ

バーにカーソルを合わせると以下の情報が確認できます:

  • コマンドテキスト
  • 成否ステータスと終了コード
  • 所要時間(ms または秒)
  • 並列グループ番号(該当する場合)
  • コマンド出力の先頭200文字

サマリーバー

ヘッダーエリアにコマンドの総数、セッション全体の所要時間、✅ / ❌ の件数が表示されます。十分な幅がある棒には所要時間ラベル(例:1.23s450ms)がインラインで表示されます。

5. 新コマンド一覧(v1.4)

コマンド 説明
extension.lc4ri.showVarInspector 変数インスペクターサイドパネルを開く
extension.lc4ri.showHistory 実行履歴ブラウザーを開く
extension.lc4ri.clearHistory 保存済みの全実行履歴を消去する
extension.lc4ri.searchOutput 直近の出力ブロック内を検索する
extension.lc4ri.showTimeline 現在のセッションのタイムラインウォーターフォールを開く

あとがき

VSCodeのエコシステムが使えるので文章校正とか他の拡張機能の恩恵も受けれますね!
これで運用作業ドキュメントも見栄え良く、使いやすくなるものと思います。

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?