概要
zshのビルトインコマンドに関して、詳細情報を知りたいと思い、
helpコマンドを叩いてみるものの、
"zsh: command not found: help" が表示されるという事象が発生。
それでは"man"の第1引数にコマンド名を渡して表示されるかというと、
出るものと出ないものがある。
例えば変数を宣言する"declare"コマンドをmanしてみると。
% man declare
No manual entry for declare
勿論helpを打ってもコマンド自体が認識されていないため通らない。
help declare
zsh: command not found: help
そもそもdeclare自体が無いのではと疑いたくなりますが、
普通にコマンドは使えます。
% declare var="hello"
% echo $var
hello
% where declare
declare: shell reserved word
declare: shell built-in command
whereでもしっかり、「ビルトインコマンドです」と返されました。
TL;DR
先に調査結果を載せておきます。
- zshでは"help"でなく"run-help"を使用する。
- デフォルトでは"run-help"は"man"のエイリアスになっている(エイリアスの解除が必要)
- "autoload -Uz run-help"でコマンドを読み込む。
- "run-help"では環境変数"HELPDIR"にマニュアルファイルのパスを通さないと対象のコマンド名を引数にして検索することができない
調査
zshのビルトインコマンド一覧をみる
こちらの記事からzshのビルトインコマンドの一覧を確認できることを知る。
ビルトインコマンドの一覧を"見やすく"見る方法
% man zshbuiltins
2767行の中から探すのは嫌...
先述のコマンドは普通にマニュアル情報も確認できるのですが、
全てのビルトインコマンドの情報が載っているので量は膨大です。
% man zshbuiltins | wc -l
2767
2767行...
勿論、検索かけることは可能ですが、
ちょっと面倒くさいですし、それが正攻法とも思えず、
ここら辺の仕様をちょっと調べてみました。
("run-help 対象コマンド"の方式で検索できるようにしたい)
Bash とは違い、Zsh は組み込みの help コマンドを有効化しておらず、代わりに run-help を提供しています。デフォルトでは、run-help は >man のエイリアスとなっています。コマンドの前に run-help と付けることで実行できますし、または今タイプしたコマンドに対してキーボードショートカッ>ト Alt+h か Esc h を入力することでも実行できます。
ArchWikiより:https://wiki.archlinux.jp/index.php/Zsh
これは、Linuxディストリビューションのひとつ、
ArchLinuxの説明を抜粋したものです。
ビルトインコマンドは"run-help"で確認できるようですが、
aliasが設定されているため、manコマンドとして機能するようです...
私の環境はMacですが、恐らく同様でしょう。
念の為aliasが設定されているか確認してみました。
ll='ls -l'
ls='ls -G'
run-help=man
which-command=whence
やはり、エイリアスが設定されてますね。
unaliasで解除したいところですが、
run-helpコマンドの仕様もよくわからないので、
まずはrun-helpがどこに格納されているか確認してみることに。
run-helpの実行ファイル格納場所
% sudo find / -name run-help -type f
/usr/share/zsh/5.8.1/functions/run-help
%
% ll /usr/share/zsh/5.8.1/functions/run-help
-rwxr-xr-x 1 root wheel 3198 2 9 18:39 /usr/share/zsh/5.8.1/functions/run-help
それっぽいのが引っ掛かりました。
中身を見る
#!/bin/zsh
#
# Figure out where to get the best help, and get it.
#
# Install this function by placing it in your FPATH and then
# adding to your .zshrc the lines:
# unalias run-help
# autoload -Uz run-help
#
※以降スクリプト処理のため省略
バイナリではなく、
普通にソースコードが確認できます。
run-helpを実行してみる。
#declareをrun-helpの引数にして実行
% /usr/share/zsh/5.8.1/functions/run-help declare
ZSHMISC(1) General Commands Manual ZSHMISC(1)
NAME
zshmisc - everything and then some
SIMPLE COMMANDS & PIPELINES
A simple command is a sequence of optional parameter assignments
followed by blank-separated words, with optional redirections
interspersed. For a description of assignment, see the beginning of
zshparam(1).
The first word is the command to be executed, and the remaining words,
if any, are arguments to the command. If a command name is given, the
parameter assignments modify the environment of the command when it is
executed. The value of a simple command is its exit status, or 128
plus the signal number if terminated by a signal. For example,
echo foo
is a simple command with arguments.
A pipeline is either a simple command, or a sequence of two or more
simple commands where each command is separated from the next by `|' or
:
"ZSHMISC(1)"なるものが立ち上がりました(最初のドキュメントとは微妙に違う)
MISCは英語の"miscellany(文集)"の略でしょうか?
文集だけあり、量は膨大で、
#"-N"で 行数を表示
2215
2216 zsh 5.8.1 February 12, 2022 ZSHM 2216 ISC(1)
(END)
2216行あります。
(wc -lだと行数が正しく表示されませんでした)
引数にビルトインコマンドを渡しましたが、特にその位置に飛んでくれるようなこともなく、
どのコマンドを渡しても必ずトップページが表示されます。
そもそも、引数はちゃんと受け渡されているのだろうか?
試しに引数なしで打ってみます。
% /usr/share/zsh/5.8.1/functions/run-help
There is no list of special help topics available at this time.
% /usr/share/zsh/5.8.1/functions/run-help hello
hello not found
No manual entry for hello
コマンドは通りません。一応ちゃんと引数を見てますね。
ちなみに、後述する方法でパスを通した後に"run-help"引数無しで実行すると、
ビルトインコマンドの一覧が表示されるようになります。
手詰まりのためネットで情報を探す
ソースコードが見えるので、run-helpの中身を確認するのも一つの手ですが、
正直面倒くさかった。
ということで、ネット検索。
しかし情報が全然引っかからない...
zshの情報ってこんな少ないの?ってくらい合致する情報が引っ掛かりません。
マニュアル確認なんて、基礎的な部分だからすぐに解決すると甘く見てました...
日本語の情報を諦め、海外の情報を探ってみる。
This is because the HELPDIR isn't set. You have to find the install location for zsh's help files and >set the env var to that dir. On my system that looks like this:
引用:https://til.hashrocket.com/posts/cxcby4mz0n-zsh-comes-with-help-set-the-helpdiryo
何やら、"HELPDIR"という環境変数を作って、そこにzshのマニュアルファイルが格納されているディレクトリを設定してあげるといったような内容が記載されております。
参考サイトの場合マニュアルファイルの場所は
/usr/share/zsh/help
が指定されておりましたが、
私の環境では以下のパスでした。
/usr/share/zsh/5.8.1/help
ls /usr/share/zsh/5.8.1/help
alias compvalues getln rehash unlimit
autoload continue getopts return unset
---省略
各ビルトインコマンドのマニュアルファイルが格納されております!
ちなみに、5.8.1 はzshのバージョンですね。
% zsh --version
zsh --version
zsh 5.8.1 (x86_64-apple-darwin22.0)
環境変数"HELPDIR"を設定する。
それではこのパスを先ほどの環境変数"HELPDIR"に設定してみます。
export HELPDIR='/usr/share/zsh/5.8.1/help'
% env
#---省略
HELPDIR=/usr/share/zsh/5.8.1/help
#---省略
それでは第1引数にビルトインコマンドを指定して実行してみる。
/usr/share/zsh/5.8.1/functions/run-help declare
typeset [ {+|-}AHUaghlmrtux ] [ {+|-}EFLRZip [ n ] ]
[ + ] [ name[=value] ... ]
typeset -T [ {+|-}Uglrux ] [ {+|-}LRZp [ n ] ]
[ + | SCALAR[=value] array[=(value ...)] [ sep ] ]
typeset -f [ {+|-}TUkmtuz ] [ + ] [ name ... ]
Set or display attributes and values for shell parameters.
#---省略
一見間違ったコマンドが引っかかっているように見えるかもしれませんが、
declareコマンドはtypesetのマニュアルへシンボリックリンクされているため正しい動作です。
% ls -l /usr/share/zsh/5.8.1/help | grep declare
lrwxr-xr-x 1 root wheel 7 2 9 18:39 declare -> typeset
これで引数を指定して対象のビルトインコマンドのページを確認することができるようになりました!
run-helpで実行できるようにする
個人的にはもう満足なのですが、
一応"run-help"のpathを通してコマンド名だけで使用できるようにしてみましょう。
% /usr/share/zsh/5.8.1/functions:ki$ alias
#---省略
run-help=man
#---省略
% unalias run-help
% autoload -Uz run-help
% run-help pwd
pwd [ -rLP ]
Print the absolute pathname of the current working directory.
If the -r or the -P flag is specified, or the CHASE_LINKS option
is set and the -L flag is not given, the printed path will not
contain symbolic links.
これで"run-help"が期待通り動くようになりました!
当初の想定よりも大分苦戦しました。
環境
OS:macOS Ventura 13.2.1
zsh:5.8.1
参考