この記事はTechBullのアドカレ2日目の記事です。
怠惰はプログラマの美徳である。
CLIはそんな怠惰人間を支えてくれる最強の相棒である。
キーボードだけで操作し、自動化を積み重ねていく。
そんな世界へ踏み込もうとすると、最初の一歩で壁にぶつかる。
本を開けば呪文のようなコマンドオプションが並び、由来もわからない。
man や help があると言われても英語がつらい。
何から手をつければいいのかもわからない。
そこで、この記事では「最初に知りたかった」 CLI の Tips を紹介していく。
現在使用しているシェルは以下の環境変数から確認できる。
$SHELL → ログインシェルの設定(標準で設定しているシェル)$0 → 現在動いてるシェル または 実行中スクリプト名# 現在のシェルを確認echo$0# ログインシェルを確認echo$SHELLこの記事では zsh を例に解説していく。
シェルを合わせたい場合は以下のコマンドで zsh に変更できる。
# 今のセッションだけzshにするzsh# デフォルトでzshを使うようにするchsh-s /bin/zshCLIツールのアップデート時に、普段使用しているコマンドが使えなくなったことがある。
こういった場合に、echo $0 とecho $SHELL を確認してみると自分のシェルの状態を確認できる。
# トラブル時の状態# 標準で使用するシェルはzsh$echo$SHELL/bin/zsh# なのに実際に起動しているシェルはbash$echo$0bashこの結果から、本来zshで起動するはずが、実際にはbashが起動してしまっていることが分かる。
そのため、zshの設定ファイルが読み込まれずコマンドが使えなくなっていたのだ。
zshの設定ファイルから、アップデートしたCLIツールの古い設定の読み込み箇所を削除し、該当のツールを再インストールすることで元に戻すことができた。
こういったトラブルシューティングにも役立つので、ぜひ覚えておいてほしい。
ぜひ最初に把握しておいてほしい物がある。それはキーバインドだ。
どのツールを使う上でも必ずキーバインドを抑えておくのが上達のコツである。
事前に取りのぞける「めんどう」は取りのぞいておこう。
もちろん全てを覚える必要はない。よく使うものから覚えていけばよい。
ところで、君は zsh のキーバインドをいくつ知っているだろうか?
せっかくなので数えてみよう。
足並みをそろえるために、まずは設定ファイルを読み込まずにまっさらなzshを起動しよう。
# 設定ファイルを読み込まずにzshを起動# zsh -fでも同じことができるzsh --no-rcsキーバインドはbindkey コマンドで確認できる。
そう、デフォルトでキーバインドのチートシートが用意されているのだ。
記憶力が乏しい私のような人間にもCLIは親切である。
# キーバインド一覧の表示bindkey実行すると以下のような内容が表示されるはずだ。
左側にキーバインド、右側にその動作が表示されている。^ は Control キーを表している。
bindkey# 出力例# "^A"-"^C" self-insert# "^D" list-choices# "^E"-"^F" self-insert# "^G" list-expand# "^H" vi-backward-delete-char# <省略>さて、ここでwc (word count) コマンドを使ってキーバインドの数を数えてみよう。-l オプションは--lines の略で、改行を数えるオプションである。
# キーバインドの数を数えるbindkey|wc-l# 出力結果31「31個も覚えられない!」と思ったかもしれない。
安心してほしい。これは重複したキーバインドも含まれている。
重複を除くならこうする。
# 重複を除外してキーバインドの数を数えるbindkey|awk'{print $2}'|sort|uniq|wc-l# 出力結果17重複を除くと17個まで減った。
案外覚えられそうな数ではないだろうか?
上のコマンドを見て、「こんなの覚えられないよ~」と思った人もいるかもしれない。
長いコマンドがでてきたら| (パイプ) ごとに実行してみると理解しやすい。
まず、bindkey コマンドだけを実行してみる。
bindkey# 出力結果# "^A"-"^C" self-insert# "^D" list-choices# ...そして、次にawk '{print $2}' をつなげてみる。
出力を比べてみると、1列目のキーバインドの表記が消え、2列目のみ表示されている。
ここで、awk '{print $2}' が「2列目を取り出す」という意味であることがわかる。
bindkey|awk'{print $2}'# 出力結果# self-insert# list-choices# ...次にsort をつなげてみる。
出力結果を見ると、重複したものがまとめられていることがわかる。
bindkey|awk'{print $2}'|sort# 出力結果# accept-line# accept-line# bracketed-paste# clear-screen# down-line-or-history# down-line-or-history# ...uniq をつなげてみると、重複が取り除かれていることがわかる。
bindkey|awk'{print $2}'|sort|uniq# 出力結果# accept-line# bracketed-paste# clear-screen# down-line-or-history# ...最後にwc -l をつなげてみると、先ほどの出力結果の行数が数えられていることがわかる。
bindkey|awk'{print $2}'|sort|uniq|wc-lこのように、長いコマンドはパイプごとに分解してみると案外理解できるものだ。
コマンドに慣れるには分解して試してみるのが一番である。
なぜsort が必要なの?
uniq は 「隣り合っている同じ行」をまとめるコマンドのため、sort で同じものを隣り合わせにしてあげる必要がある。
ちなみに、'awk' だけで重複を除いて数える方法もある。
bindkey|awk'{a[$2]++} END {print length(a)}'a に$2 をキーとしてカウントlength(a) で出すbindkey と同じように、エイリアス一覧や関数一覧を表示するコマンドもある。
引数を渡すと、その名前のエイリアスや関数の内容を表示してくれる。
# エイリアス一覧の表示alias# 関数一覧の表示functions実はシェルのキーバインドにはvimモードとemacsモードがある。
現在のキーバインドモードを確認するには以下のコマンドを実行しよう。
# キーバインドモードの確認bindkey-lL main# 出力例# vimモードの場合# bindkey -A viins main# emacsモードの場合# bindkey -A emacs mainたいていの環境では emacsモードがデフォルトになっているため、emacsモードに変更することをオススメする。
# emacsモードに変更bindkey-eこれは余談だが、 emacs モードの方がキーバインドの数が多い。
bindkey|awk'{print $2}'|sort|uniq|wc-l# 69この設定を今回のセッションだけではなく、永続化したい場合は zshの設定ファイル (~/.zshrcなど) に追記しよう。
bindkey-eまた、設定ファイルを更新したら以下のコマンドで再読み込みしよう。
# 設定を読み直すために、ログインシェルとして起動しなおすexec$SHELL-lキーバインド一覧の中から、特によく使うものをピックアップして紹介しよう。
まずはここから。
# Mac標準でも使える"^F" forward-char# 1文字右へ移動"^B" backward-char# 1文字左へ移動"^P" up-line-or-history# ひとつ前の履歴を呼び出す (↑)"^N" down-line-or-history# ひとつ次の履歴 (↓)"^A" beginning-of-line# 行頭へ移動"^E" end-of-line# 行末へ移動"^D" delete-char-or-list# カーソル位置の文字を削除 何も無い行で押すとシェル終了"^K" kill-line# カーソル以降を削除"^Y" yank# ^K や ^W などで消したものを貼り付け"^T" transpose-chars# 隣り合う2文字を入れ替える (typo直しに便利)# シェルで使える"^H" backward-delete-char# バックスペース"^W" backward-kill-word# 1単語削除"^U" kill-whole-line# 行全削除"^L" clear-screen# 画面クリア (clear コマンドと同じ)意外と知られていないのに便利なやつ。
"^Q" push-line# 今入力している行を一時退避. 別のコマンドを打って戻りたい時に便利"^_" undo# 編集の取り消し# Metaキー (^[) 系"^[f" forward-word# 単語単位で右へ移動"^[b" backward-word# 単語単位で左へ移動"^[q" push-line# 行退避. ^Q がターミナル側で使われている環境向け"^[." insert-last-word# 直前のコマンドの「最後の引数」を挿入 連打でさらに遡れる"^[H" run-help# 現在入力中のコマンドのヘルプを開く (zsh固有)"^[?" which-command# カーソル位置の単語がどのコマンドかを表示(zsh固有). PATH上の実体も確認できるMetaキーとは?
^[ という表記はMetaキー を表している。
次のどちらかで入力できる。
なぜ同じになるのかというと、Altキーは内部的に
「ESC を送ってから文字を送る」という入力になっているため。
Altキーが効かない場合はターミナルの設定で「AltキーをMetaキーとして扱う」ようにする必要がある。bindkey | grep "^[\"']\^\[" でMetaキー系のキーバインドだけを抽出できる。
初期状態だと、run-help はman コマンドのエイリアスになっているだけで、zsh固有のヘルプ機能が使えない。
# run-help の実態を確認type run-help# run-help is an alias for manrun-help=manの設定は zsh の ソースコード内でされている
zsh/Src/hashtable.c/* add the default aliases */aliastab->addnode(aliastab, ztrdup("run-help"), createaliasnode(ztrdup("man"), 0));aliastab->addnode(aliastab, ztrdup("which-command"), createaliasnode(ztrdup("whence"), 0));ref:https://github.com/zsh-users/zsh/blob/master/Src/hashtable.c#L1214-L1216
zsh固有のヘルプ機能を使うには、以下の設定を追加しよう。
unalias run-help 2>/dev/nullautoload -Uz run-help設定すると、 run-help の実態が関数になっていることが確認できる。
type run-help# run-help is a shell function from /usr/share/zsh/5.9/functions/run-helprun-helpの関数の中身はfunctions run-help で確認できる。
この設定により、functions コマンドのような、man では見つからない zsh 固有のコマンドのヘルプも開けるようになる。
# man で開こうとしてもマニュアルが見つからないman functions# No manual entry for functionsコマンドを入力してESC→H (run-help) を実行すると、マニュアルが見つかる。
# コマンドを入力してfunctions# ESC→H でマニュアルが開く
/^ *functionsで検索して該当箇所にジャンプできる

Control + z を押すと、今のコマンドが一時停止 (suspend) する。
しかし、bindkey を見ても、そのキー設定は出てこない。
これはなぜか?
じつは、シェルに文字を送るまでには “二つの層” がある。
[ キーボード ] ↓[ 端末(tty) ← OS がキー入力を先に処理する場所 ] ↓[ シェル(zsh / bash) ← bindkey が見ているのはここだけ ] ↓[ コマンド実行 ]bindkey が教えてくれるのは、シェルが持っているキーバインドだけ。
一方でControl + z のような「プロセスを止めるキー」は、OS の端末(tty) が先に処理している。
そのため、Control + z は使えるのに、bindkey の一覧には出てこないのだ。
端末(tty)で使えるキーはstty -a で確認できる。
# 端末 (tty) の設定を表示stty-a# 出力結果# <省略># cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;# eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;# min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;# stop = ^S; susp = ^Z; time = 0; werase = ^W;ちなみに、suspend (一時停止) したプロセスはfg コマンドで再開できる。
# 直前の一時停止したプロセスを再開fg# suspend したプロセスの確認jobs# 再開したいジョブを指定して再開fg %2私はControl + z でsuspendをトグルできるようにしている。
プロセス実行中にControl + z を押すと一時停止、再度Control + z を押すと再開する。
#! /usr/bin/env zshfancy-ctrl-z(){if[[$#BUFFER-eq0]];thenBUFFER=" fg" zle accept-lineelse zle push-inputfizle clear-screen}zle-N fancy-ctrl-zbindkey'^Z' fancy-ctrl-z参照:
デフォルトで設定されていないキーバインドたち。
全部知ってる人はシェルマスター。
'^X^R' redo# 実はデフォルトで設定されていない'^[e' edit-command-line# 現在行を $EDITOR で編集'^p' history-beginning-search-backward-end# 入力内容で前方一致検索'^n' history-beginning-search-forward-end# 入力内容で前方一致検索それぞれのキーバインドについて紹介してく。
undo は知ってるのに redo を使っていない人はけっこう多い。
以下のように設定しておくと、Control-_ (undo) をしすぎた時に、Control-x Control-r でやり直しができる。
# Control-x Control-r で redobindkey'^X^R' redoコマンドを編集しているとふと vim のキーバインドが恋しくなる時がある。
そんな時はedit-command-line がオススメだ。
以下の設定を追加しておくと、Esc→e で現在の行を$EDITOR で開けるようになる。
# edit-command-line を読み込むautoload-Uz edit-command-linezle-N edit-command-line# Esc→e (Alt-e) で現在行を $EDITOR で編集bindkey'^[e' edit-command-lineControl-p / Control-n を単なる履歴の上下ではなく、今入力している文字列で前方一致する履歴だけをたどることができる。
例えば、docker と入力してから Control-p を押すと、docker で始まる過去のコマンドだけをたどれる。
前方が一致している単語だけをたどるので、目的のコマンドにたどり着きやすい。
設定は以下の通り。
# 前方一致履歴検索のベースになるウィジェットを読み込むautoload-Uz history-search-end# 前方一致しながら行末にカーソルを置くウィジェットを定義zle-N history-beginning-search-backward-end history-search-endzle-N history-beginning-search-forward-end history-search-end# Control-p / Control-n を前方一致履歴検索に割り当てbindkey'^p' history-beginning-search-backward-endbindkey'^n' history-beginning-search-forward-end使えるコマンドを増やしたい、でも何をどこまで抑えておくべきかわからない。
そんな時に便利なのが tldrコマンド である。
実用的な使用例に焦点を当てた、より簡潔なヘルプを確認することができる。
インストールは Homebrew で簡単にできる。
# tlrcをインストールbrewinstall tlrc例えば、wc コマンドの使い方を知りたいときは以下のように実行する。
# tldrでwcの使い方を確認tldrwc実行すると以下のようなコマンドの使い方の要約が確認できる。

tldrコマンドでwcコマンドの使い方を確認
オプションといえば、ls -laでいう-laの部分である。
そう、あのパっとみて何かわからないやつのことである。
オプションは何の略か確認すると頭に入りやすい。
そんな時に使えるのが--help とman である。
例えば、tldr のコマンドオプションを確認したいときは以下のように実行する。
tldr--help# Options:# -u, --update Update the cache# -l, --list List all pages in the current platform# -a, --list-all List all pages出力を見ると、-u は--update の略であることがわかる。
また、manコマンドでより詳しい情報を確認することもできる。
man tldr
man tldrの出力
このように--help とman はコマンドの使い方を知る上で最高の情報源である。
しかし、英語が苦手な人にとっては読むのがつらい。
そんな人にオススメの対処方法を紹介していく。
英語がつらい人にぜひ試してほしいのが PLaMo翻訳 である。
ブラウザの拡張機能とCLIツールの両方が提供されている。
PLaMo翻訳の紹介スライドもあるのでぜひ見てほしい。
拡張機能版はサブスク形式で提供されているが、無料で試せるFreeプランも用意されている。
ページのレイアウトを崩さずに翻訳できる上に、ショートカットキーひとつで実行できる手軽さが魅力である。
一度使うと作業の流れがグッと快適になり、手放せなくなるツールのひとつになるはず。

動作している様子
単語単位で知りたい場合はMouse Dictionaryという拡張機能もオススメだ。
ホバーした単語の意味をポップアップで表示してくれる。

ポップアップウィンドウのカスタマイズはCSSできるため、自分好みにできるのも嬉しいポイント。
plamo-translate-cli は、plamo-2-translate という翻訳用の言語モデルをローカル環境で使うためのCLIツールである。
インストールは uv コマンドで簡単にできる。
# plamo-translate-cliをインストールuv toolinstall plamo-translate-cli# uvが無い場合は以下のコマンドでインストールbrewinstall uv| plamo-translate --to <言語> のようにパイプで繋いで使うことができる。
# plamo-translateのプロセスを起動# これによりモデルの読み込み時間をスキップできるplamo-translate server# tldr wcの出力を日本語に翻訳tldrwc| plamo-translate--to Japanese
実際に翻訳してみた様子
plamo-translate-cli のプロセス用にタブを一つ占有するのはもったいない。
そんな時に便利なのが Ghost である。
Ghost は シンプルなバックグラウンドプロセス管理ツールで、TUIでプロセスの状態を確認できる。

公式ドキュメントより引用
git clone https://github.com/skanehira/ghost.gitcd ghostcargo build--releaseビルドが失敗する場合は、GitHubリポジトリに記載されたRequirementsを満たしているか確認しよう。
Requirements
- Unix-based system (Linux, macOS, BSD)
- Rust 1.80+ (2024 edition)
- lsof (optional, used for port detection)
ghost run <管理したいコマンド> でバックグラウンド実行できる。
なので、plamo-translate-cli のサーバーのプロセスを ghost で管理するには以下のコマンドを実行すればよい。
# ghost run で plamo-translateのサーバーをバックグラウンド実行ghost run plamo-translate serverプロセスはghost コマンドで確認できる。
# TUIでプロセス管理ghostここまでで help や tldr を使ってコマンドの使い方を調べる方法を紹介した。
せっかくならman コマンドも日本語で読みたい と感じる人もいるはず。
じつは man の日本語マニュアルを翻訳・公開している JM Project というプロジェクトがある。
ここで配布されている日本語 man ページを入れておくと、標準コマンドの説明を自然な日本語で読めるようになる。
マニュアルのダウンロード手順は以下の通り。
ダウンロードリンクはこちらにあったものを使用している。
Release v20251115 · linux-jm/manual
# 作業用のディレクトリへ移動 (自分はDownloadsディレクトリにした)cd ~/Downloads# manの日本語マニュアルページをダウンロードcurl-L-O https://github.com/linux-jm/manual/releases/download/v20251115/man-pages-ja-20251115.tar.gz# ダウンロードしたファイルを展開tar xfz man-pages-ja-20251115.tar.gz# 展開されているかチェックls|grepman# man-pages-ja-20251115# man-pages-ja-20251115.tar.gz# 展開したディレクトリに移動cd man-pages-ja-20251115インストールの際に、インストール先、 ユーザー、グループを指定する必要がある。
必要な情報をあらかじめ確認しておこう。
# ユーザー名を確認$whoamimozumasu# グループ名を確認$id-gnstaff# マニュアルのインストール先のディレクトリが存在しているか確認$ls-d${HOME}/.local/share/man# 存在しない場合は作成mkdir-p${HOME}/.local/share/manインストールの設定を行うには、展開したディレクトリに移動してmake config を実行する。
# インストール設定make config# インストール先、ユーザー名、グループ名を指定する# 他の項目はデフォルトのままでよいので、Enterキーを押して進める[INSTALLATION INFORMATION](just Returnif you accept default) Install directory[/usr/share/man/en_US.UTF-8] ?:${HOME}/.local/share/man compress manual with..0: none1:gzip2:bzip23: compressselect[0..3]:uname of page owner[root] ?: mozumasu group of page owner[root] ?: staff Directory:${HOME}/.local/share/man Compression: none Page uid/gid: mozumasu/staffAll OK?(Yes,[C]ontinue / No,[R]eselect): Y# 残りはEnterキーを押して進める設定が完了したら、make install でインストールを実行する。
makeinstall以下のメッセージが出力されたらインストール完了である。
# インストール中の出力-ninstall GNU_gzip: zmore.1..done.-ninstall GNU_gzip: znew.1..done.試しにインストールしたマニュアルでls コマンドを確認してみよう。-M で使用するマニュアルのパスを指定できる
man-M${HOME}/.local/share/manlsうまくインストールができていれば日本語のマニュアルが表示される。

毎回パスを設定するのは面倒なので、zshの設定ファイル (~/.zshrcなど) にマニュアルのパスを追加しておくとman ls で日本語のマニュアルを参照することができる。
exportMANPATH="$HOME/.local/share/man:$MANPATH"せっかくならカラーでマニュアルが見れたら便利だとは思わないだろうか?MANPAGER 環境変数で lessコマンド を指定し、LESS_TERMCAP 系の環境変数を設定することで色を付けることができる。
exportMANPAGER=less# man 専用ページャーとして less を使うexportLESS=-R# 色付き表示を保持exportLESS_TERMCAP_mb=$'\e[1;31m'# 強調 赤exportLESS_TERMCAP_md=$'\e[1;34m'# 太字 青exportLESS_TERMCAP_me=$'\e[0m'# resetexportLESS_TERMCAP_so=$'\e[7m'# 反転exportLESS_TERMCAP_se=$'\e[0m'exportLESS_TERMCAP_us=$'\e[4;32m'# 下線 緑exportLESS_TERMCAP_ue=$'\e[0m'この設定を追加して再度man ls を実行するとカラーで表示されるようになる。

lessでmanをカラー表示
もちろん、 man の表示に Neovim を使うこともできる。
exportMANPAGER='nvim +Man!'この状態でman ls を実行すると、 Neovim でマニュアルが開くようになる。

Neovimでmanを表示
この設定は Neovim のヘルプに記載があるので、設定を忘れてしまった場合は:h :Man@en で確認しよう。

Neovimからマニュアルを開きたい場合は、:Man コマンド名 で開ける。
シェルスクリプトを書いている時はK でマニュアルを開くこともできる。

Neovimでカーソル位置のコマンドのマニュアルを開く
Neovimが無い場合は以下のコマンドでインストールできる。
brewinstall neovimお試しでリッチな設定がされたNeovimを使いたい場合は、LazyVimがオススメだ。
すぐに使い始められるNeovimを体験できる。
LazyVim のインストール手順は以下の通り。
# 既に~/.config/nvimが存在する場合はバックアップを取っておくmv ~/.config/nvim{,.bak}mv ~/.local/share/nvim{,.bak}mv ~/.local/state/nvim{,.bak}mv ~/.cache/nvim{,.bak}# LazyVimのスターターを~/.config/nvimにクローンgit clone https://github.com/LazyVim/starter ~/.config/nvim# 後で自分のリポジトリで管理できるように .git フォルダを削除rm-rf ~/.config/nvim/.git# Neovimを起動してプラグインをインストールnvimNeovim で開くと、プラグインで翻訳 もできるので日本語版のマニュアルが無いコマンドでも安心だ。
最初に知りたかった CLI の Tips を紹介してきた。
参考になれば幸いである。
謝辞
Vim-jp Slack の tech-cli チャンネルにてフィードバックをくださった皆様、ありがとうございました!🙇
明日のTechBullのアドカレ は Ryo Ninomiya さんの記事です! おたのしみに!
バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。
