Command-Line

為什麼 shell 內置函式沒有適當的手冊頁?

  • November 14, 2017

所有 shell 內置程序共享相同的手冊頁:

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

NAME
    builtin, !

等等

然後是一段描述什麼是 shell 內置函式的小文本,然後是一個看起來像這樣的列表:

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

但是如果我們這樣做,man grep我們會得到諸如

  • 錯誤
  • 歷史
  • 也可以看看
  • 標準
  • 描述

等等

shell 內置函式沒有自己的歷史、描述和參數,比如-Aor-r嗎?為什麼手冊頁中沒有提供這些內容,我將如何學習正確有效地使用它們?

因為內置函式是外殼的一部分。他們擁有的任何錯誤或歷史都是 shell 本身的錯誤和歷史。它們不是獨立的命令,也不存在於它們內置的外殼之外。

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 列印手冊頁的相關部分。將此行添加到 shell 的初始化文件(~/.bashrc對於 bash):

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).

引用自:https://unix.stackexchange.com/questions/167004