シェル組み込みコマンドに適切なマニュアルページがないのはなぜですか?

シェル組み込みコマンドに適切なマニュアルページがないのはなぜですか?

すべてのシェル組み込み機能は同じマニュアルページを共有します。

BUILTIN(1)                BSD General Commands Manual               BUILTIN(1)

NAME
     builtin, !

など。

次に、シェル組み込みコマンドが何であるかを説明する短い段落と、次のようなリストがあります。

  Command       External    csh(1)    sh(1)
       !             No          No        Yes
       %             No          Yes       No

しかし、これを行うと、man grep次のような結果が得られます。

  • 昆虫
  • 歴史
  • また、見ることができます
  • 基準
  • 説明する

など。

シェル組み込み関数には、-Aまたはなどの自己記録、説明、およびパラメータはありませんか-r?マニュアルページでこれらのコンテンツが提供されていないのはなぜですか、それを正確かつ効率的に使用する方法を学ぶ方法は?

答え1

組み込み関数はシェルの一部であるからです。彼らが持っているすべてのエラーや記録はシェル自体のものです。これはスタンドアロンコマンドではなく、ビルドされたシェルの外部にも存在しません。

少なくともそれに対応するのはコマンドbashです。helpたとえば、

$ help while
while: while COMMANDS; do COMMANDS; done
    Execute commands as long as a test succeeds.

    Expand and execute COMMANDS as long as the final command in the
    `while' COMMANDS has an exit status of zero.

    Exit Status:
    Returns the status of the last command executed.

すべてのbash組み込み機能にはhelpページがあります。それ自体もhelp

$ help help
help: help [-dms] [pattern ...]
    Display information about builtin commands.

    Displays brief summaries of builtin commands.  If PATTERN is
    specified, gives detailed help on all commands matching PATTERN,
    otherwise the list of help topics is printed.

    Options:
      -d    output short description for each topic
      -m    display usage in pseudo-manpage format
      -s    output only a short usage synopsis for each topic matching
        PATTERN

    Arguments:
      PATTERN   Pattern specifiying a help topic

    Exit Status:
    Returns success unless PATTERN is not found or an invalid option is given.

@mikeservsedのスクリプトに触発され、Perlを使用してマニュアルページの関連部分を印刷する小さな関数があります。シェルの初期化ファイル(~/.bashrcbashの場合)に次の行を追加します。

manperl(){ man "$1" | perl -00ne "print if /^\s*$2\b/"; }

次に、マニュアルページとセクション名を指定して実行します。

$ manperl bash while
       while list-1; do list-2; done
       until list-1; do list-2; done
              The while command continuously executes the list list-2 as long as the last command in the list list-1 returns an exit
              status of zero.  The until command is identical to the while command, except that the test is negated; list-2 is  exe‐
              cuted  as  long  as the last command in list-1 returns a non-zero exit status.  The exit status of the while and until
              commands is the exit status of the last command executed in list-2, or zero if none was executed.

$ manperl grep SYNOPSIS
SYNOPSIS
       grep [OPTIONS] PATTERN [FILE...]
       grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

$ manperl rsync "-r"
       -r, --recursive
              This tells rsync to copy directories recursively.  See also --dirs (-d).

答え2

一部のシェル組み込み機能がマニュアル全体にほとんど表示されないのは事実ですが、特にbashGNUシステムでのみ使用可能な特定の組み込み機能はさらにそうです。(GNUの人々は通常これを信じておらず、man自分のinfoページを好む)- ほとんどのPOSIXユーティリティ(シェルが組み込まれているかどうかなど)は、POSIXプログラマガイドでよく扱われています。

これは私の底から抜粋したものです。man sh (約20ページ程度...)

ここに画像の説明を入力してください。

それらのすべてがそこにあり、言及されていない他の人もいます。たとえばset…まあ、すべて名前を付ける必要はありません。しかし、右下にPOSIX Category 1 Manual Seriesと書かれています。これが私が言うページです。readbreak(1P)man

おそらく1つのパッケージをインストールするだけですか?これDebian システムは有望に見えます。役に立ちますが、そのシリーズが見つかる場合はhelp必ず購入する必要があります。POSIX Programmer's Guideこれは非常に役立ちます。設定ページは非常に詳細です。

それに加えて、シェルの組み込み機能は、ほぼ常にその特定のシェルのマニュアルの特定のセクションにリストされています。zshたとえば、完全に別々のページがありますmanzsh(合計8~9ページほどだったと思います。zshallすごいです。)

もちろんあなたはできますgrep man

man bash 2>/dev/null | 
grep '^[[:blank:]]*read [^`]*[-[]' -A14

   read [-ers] [-a aname] [-d  delim]  [-i  text]  [-n
   nchars]  [-N  nchars]  [-p prompt] [-t timeout] [-u
   fd] [name ...]
          One line is read from the standard input, or
          from  the  file descriptor fd supplied as an
          argument to the -u  option,  and  the  first
          word is assigned to the first name, the sec‐
          ond word to the second name, and so on, with
          leftover words and their intervening separa‐
          tors assigned to the last  name.   If  there
          are  fewer  words read from the input stream
          than names, the remaining names are assigned
          empty  values.   The  characters  in IFS are
          used to split the line into words using  the
          same  rules  the  shell  uses  for expansion

...これは私がシェルページを検索したときにやっていたものとかなり似ていますman。しかし、ほとんどの場合、helpかなり良いです。bash

私は実際にsedこの種のことを処理するために最近スクリプトを書いています。上の写真の部品をこんなに握りました。まだ私が望むよりも長いが、ますます改善されており、非常に便利です。現在の反復では、コマンドラインで提供されている[a]パターンに基づいて、セクションまたはサブセクションのタイトルに一致するテキストのコンテキストに合った部分を非常に確実に抽出します。出力に色を付け、標準出力として印刷します。

インデントレベルを評価して機能します。空でない入力行は通常無視されますが、空行に遭遇すると注意を払い始めます。別の空行が表示される前に、現在のシーケンスが実際に最初の行よりもインデントされていることを確認するまで、そこから行を収集します。それ以外の場合は、スレッドを削除して次のスペースを待ちます。テストが成功すると、リードラインをコマンドライン引数と一致させようとします。

これは次のことを意味しますマッチパターンは次のように一致します。

heading
    match ...
    ...
    ...
        text...

..そして..

match
   text

..しかし..

heading
    match
    match

    notmatch

..または..

         text

         match
         match
         text

         more text

一致する場合は印刷が始まります。印刷するすべての行から一致する行の先頭のスペースを削除するので、インデントのレベルに関係なく、一番上にあるように印刷します。一致する行よりもインデントレベルが同じまたは小さい他の行に会うまで印刷を続けます。したがって、ヘッダー一致のみを含むことができるすべてのサブセクション、段落を含むセクション全体を取得します。

したがって、デフォルトでは特定のパターンと一致するように要求すると、特定のトピックのタイトルとのみ一致し、一致の最初のセクションのすべてのテキストに色を付けて印刷します。最初の行のインデント以外は何も保存しません。したがって、非常に高速で、\nほぼすべてのサイズの行で区切られた入力を処理できます。

次の字幕に再帰する方法を見つけるのに時間がかかりました。

Section Heading
    Subsection Heading

しかし、私はついにそれを見つけました。

しかし、単純さのためにすべてを再設計する必要がありました。以前は、コンテキストに合わせてわずかに異なる方法でほぼ同じことを行ういくつかの小さなループがありましたが、再帰的な方法を変更してほとんどのコードの重複を排除しました。今、2つのループがあります。 1つは印刷し、もう1つはインデントを確認します。どちらも同じテストに依存します。テストが合格すると印刷ループが開始され、テストが失敗した場合、または空白行から開始するとインデントループが続きます。

ほとんどの場合、/./d空でない行を削除して次の行に移動するため、プロセス全体が非常に高速です。結果もzshallすぐに画面に埋め込まれます。これは変わらなかった。

とにかく今まではとても便利でした。たとえば、read上記の操作は次のように実行できます。

mansed bash read

...全体のブロックを得ました。どのパターンでも何でも使用でき、複数のパラメータを使用できますが、最初のパラメータは常にman検索する必要があるページです。これは写真です一部これを実行した後の出力は次のとおりです。

mansed bash read printf

ここに画像の説明を入力してください。

...両方のチャンクがそのまま返されます。私はしばしば次のように使用します。

mansed ksh '[Cc]ommand.*'

...とても便利です。また、次のようにSYNOPS[ES]取得するのは非常に便利です。

ここに画像の説明を入力してください。

一度やりたいならこれが全部です。そうでなくても、私はあなたを責めることはありません。

mansed() {
MAN_KEEP_FORMATTING=1 man "$1" 2>/dev/null | ( shift
b='[:blank:]' s='[:space:]' bs=$(printf \\b) esc=$(printf '\033\[') n='\
' match=$(printf "\([${b}]*%s[${b}].*\)*" "$@")
sed -n "1p
    /\n/!{  /./{    \$p;d
        };x;    /.*\n/!g;s///;x
    :indent
        /.*\n\n/{s///;x
        };n;\$p;
        /^\([^${s}].*\)*$/{s/./ &/;h;   b indent
        };x;    s/.*\n[^-[]*\n.*//; /./!x;t
        s/[${s}]*$//;   s/\n[${b}]\{2,\}/${n} /;G;h
    };
    #test
    /^\([${b}]*\)\([^${b}].*\n\)\1\([${b}]\)/!b indent
        s//\1\2.\3/
    :print
    /^[${s}]*\n\./{ s///;s/\n\./${n}/
        /${bs}/{s/\n/ & /g;
            s/\(\(.\)${bs}\2\)\{1,\}/${esc}38;5;35m&${esc}0m/g
            s/\(_${bs}[^_]\)\{1,\}/${esc}38;5;75m&${esc}0m/g
            s/.${bs}//g;s/ \n /${n}/g
            s/\(\(${esc}\)0m\2[^m]*m[_ ]\{,2\}\)\{2\}/_/g
        };p;g;N;/\n$/!D
        s//./;  t print
    };
    #match
        s/\n.*/ /;  s/.${bs}//g
        s/^\(${match}\).*/${n}\1/
        /../{   s/^\([${s}]*\)\(.*\)/\1${n}/
        x;  s//${n}\1${n}. \2/; P
    };D
");}

簡単に言えば、ワークフローは次のようになります。

  • 空白ではなく、\n改行文字を含まない行は出力から削除されます。
    • \newline 文字は入力パターン空間には表示されません。編集の結果としてのみ存在できます。
  • :printどちら:indentも相互依存的な閉ループであり、\newlineを取得する唯一の方法です。
    • :print行の先頭の文字が一連の空白で、その後に改行文字がある場合は、ループサイクルが\n始まります。
    • :indentループは空行(または:print失敗したループ行)で始まりますが、#test出力から:indentすべての先行スペースと改行\nシーケンスを削除します。
    • :print起動したら、入力行を引き続き取得し、ループの最初の行にある数字で先行スペースを削除し、サムとアンダータップのバックスペースエスケープをカラーターミナルエスケープに変換し、失敗#testするまで結果を印刷します。
    • 始める前に、最初にインデントされ:indenth連続が可能であることを確認してください。(例:セクション)その後、失敗するたびに#test入力を引き続き取得すると、最初の行以降のすべての行が一致し続けます[-。最初の行以降の行がパターンと一致しない場合は削除されます。その後、すべての後続行は次の空行まで削除されます。
  • #match#test2つの閉じたループを接続します。
    • #test先頭の空白シーケンスが\n行シーケンスの最後の行の後の空白シーケンスより短い場合に渡されます。
    • #match\nコマンドライン引数に一致する出力シーケンスに:printループを開始するために必要な先行を追加します。:indent存在しないシーケンスは空白としてレンダリングされ、結果として生成された空白行は再度渡されます:indent

答え3

各シェルには独自の組み込み機能セットがあります。共通点がありますが、すべて文書化する必要がある固有の特性があります。

LinuxやFreeBSD(およびFreeBSDの後続のOSX)などのシステムでは、各シェルは別々のパッケージで提供されるため、組み込みコマンドのマニュアルページはなく、代わりに各組み込み機能はシェルのマンページです。したがって、bashの組み込み機能についてはbashのマニュアルページをkill、dashの組み込み機能についてはdashのマニュアルページを読んでくださいkillkillスタンドアロンユーティリティのマニュアルページもあります。

バラよりBash 組み込みコマンドの個別のマニュアルページを取得できますか?man引数が組み込み関数の名前の場合、関数のマニュアルページの代わりにbash内部文書が表示されます。

一部のUnixバリアントは、シェル組み込みコマンドのマニュアルページを提供します。実際、ほとんどの商用バリアントはそうします。これは、システムが単一のシェルまたは既知のシェルセットと共に提供されるので可能である。マニュアルページでは、シェル間の違いについて説明します。例えば、fg(1)Solaris 10 のマニュアルページshkshおよび部分がありますcsh。これfg(1)AIX 7.1のマニュアルページ「Kornシェル」と「POSIXシェル」を参照しながら一緒に議論します(2つはまったく同じ機能をサポートしますfg)。これfg(1)Tru64 5.0 マニュアルページksh 組み込み機能について説明し、csh ユーザーにcsh(1)マニュアルページを参照します。上海協力機構明らかにケースが付属しています。これらのオペレーティングシステムには、アドインパッケージで別のシェルをインストールできます。カスタムシェルを使用している場合は、デフォルトシェルではなくシェルを使用するときは、組み込み機能のマニュアルページが関連していないことに注意してください。

関連情報