“which”是内置命令吗?我可以覆盖它吗?

“which”是内置命令吗?我可以覆盖它吗?

在 openSUSE 中,“which”命令实际上会更新,并且很可能是一个单独的应用程序,而在其他一些发行版中,它是一个内置命令。

那么,如果 PATH 中有一个“which”命令,它会覆盖默认的内置命令吗?

这是否适用于 cd 命令和其他内置命令?

笔记:https://software.opensuse.org/package/which

答案1

你有很多问题。让我们尝试回答他们:

“which”是内置命令吗?

是的

  • 某些 shell 中的内置命令(csh、tcsh 和 zsh),
  • (lksh、mksh、ksh93 和 attsh) 中的跟踪别名(shelltype which为散列命令打印的内容(阅读有关内容))和hash
  • (dash、bash、yash)中的外部应用程序。

因此,没有一个普遍的简单答案。

我可以覆盖它吗?

执行顺序始终是别名、特殊内置函数(以及在 PATH 中搜索后)函数、常规内置函数和外部实用程序。

覆盖:

  • 一个特殊的内置函数使用别名,
  • 常规内置函数(应该是什么)使用别名或函数。
  • 而且,如果使用 PATH,您始终可以在其他可执行文件之前添加可执行文件。
  • 此外,某些 shell 可能会提供额外的内置控件,例如路径搜索中的 (%builtin)Minix I (1989) 灰壳或者在 ksh、bash、zsh 中启用/禁用

在 openSUSE 中,“which”命令是一个单独的应用程序吗?

是的,Fedora、Debian 和许多其他系统也是如此。但是,贝壳在这方面可能有其特殊的发言权。

它是其他发行版中的内置命令吗?

这更多地取决于您使用的 shell,而不是发行版决定将哪些文件作为可用文件。发行版选择文件,外壳程序选择内置文件。

路径中的“which”命令会覆盖默认的内置命令吗?

不,因为应用程序是执行搜索序列中最后执行的元素。

这是否也适用于 cd 命令和其他内置命令?

Acd是一个常规的内置的,因此它可以被别名或函数覆盖(在 Posix 术语中:仅当路径中存在同名的可执行文件时)。

答案2

which是 zsh 中内置的,但大多数其他 shell 中不是内置的。如果您使用 zsh 和 invoke which,它将使用内置 shell,这是命令和内置 shell 共享相同名称时的典型行为。

如果您想调用该命令,则 POSIX 提供了command内置命令来执行此操作:command which。如果您想知道命令所在的位置,POSIX 方法是command -v.

答案3

使用以下方法很容易找到which

在 Fedora 32 上:

$ which which
alias which='(alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot'
    /usr/bin/which

$ rpm -qf /usr/bin/which
which-2.21-19.fc32.x86_64

所以,一个单独的命令。

答案4

$ help
 alias [-p] [name[=value] ... ]          logout [n]
 bg [job_spec ...]                       mapfile [-d delim] [-n count] [-O or>
 bind [-lpsvPSVX] [-m keymap] [-f file>  popd [-n] [+N | -N]
 break [n]                               printf [-v var] format [arguments]
 builtin [shell-builtin [arg ...]]       pushd [-n] [+N | -N | dir]
 caller [expr]                           pwd [-LP]
 case WORD in [PATTERN [| PATTERN]...)>  read [-ers] [-a array] [-d delim] [->
 cd [-L|[-P [-e]] [-@]] [dir]            readarray [-d delim] [-n count] [-O >
 command [-pVv] command [arg ...]        readonly [-aAf] [name[=value] ...] o>
 compgen [-abcdefgjksuv] [-o option] [>  return [n]
 complete [-abcdefgjksuv] [-pr] [-DEI]>  select NAME [in WORDS ... ;] do COMM>
 compopt [-o|+o option] [-DEI] [name .>  set [-abefhkmnptuvxBCHP] [-o option->
 continue [n]                            shift [n]
 coproc [NAME] command [redirections]    shopt [-pqsu] [-o] [optname ...]
 declare [-aAfFgilnrtux] [-p] [name[=v>  source filename [arguments]
 dirs [-clpv] [+N] [-N]                  suspend [-f]
 disown [-h] [-ar] [jobspec ... | pid >  test [expr]
 echo [-neE] [arg ...]                   time [-p] pipeline
 enable [-a] [-dnps] [-f filename] [na>  times
 eval [arg ...]                          trap [-lp] [[arg] signal_spec ...]
 exec [-cl] [-a name] [command [argume>  true
 exit [n]                                type [-afptP] name [name ...]
 export [-fn] [name[=value] ...] or ex>  typeset [-aAfFgilnrtux] [-p] name[=v>
 false                                   ulimit [-SHabcdefiklmnpqrstuvxPT] [l>
 fc [-e ename] [-lnr] [first] [last] o>  umask [-p] [-S] [mode]
 fg [job_spec]                           unalias [-a] name [name ...]
 for NAME [in WORDS ... ] ; do COMMAND>  unset [-f] [-v] [-n] [name ...]
 for (( exp1; exp2; exp3 )); do COMMAN>  until COMMANDS; do COMMANDS; done
 function name { COMMANDS ; } or name >  variables - Names and meanings of so>
 getopts optstring name [arg]            wait [-fn] [id ...]
 hash [-lr] [-p pathname] [-dt] [name >  while COMMANDS; do COMMANDS; done
 help [-dms] [pattern ...]               { COMMANDS ; }
root@machinexa:~# help | grep which
root@machinexa:~# 

哪个不是 bash 内置函数?如果我错了,请评论另外要查看路径env $PATH,您还可以检查每个路径中的哪个路径,例如ls /usr/bin/which/usr/bin 被所有路径替换

相关内容